diff --git a/HIRS_Utils/src/main/java/hirs/utils/BannerConfiguration.java b/HIRS_Utils/src/main/java/hirs/utils/BannerConfiguration.java index 0f5d1fc5..1b46720d 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/BannerConfiguration.java +++ b/HIRS_Utils/src/main/java/hirs/utils/BannerConfiguration.java @@ -23,14 +23,16 @@ import java.util.Properties; public class BannerConfiguration { private static final Path BANNER_PROPERTIES_PATH = FileSystems.getDefault() - .getPath("/opt/tomcat/webapps/HIRS_AttestationCAPortal", "WEB-INF", "classes", "banner.properties"); + .getPath("/opt/tomcat/webapps/HIRS_AttestationCAPortal", + "WEB-INF", "classes", "banner.properties"); private static final String BANNER_COLOR = "banner.color"; private static final String BANNER_STRING = "banner.string"; private static final String BANNER_DYNAMIC = "banner.dynamic"; private static final String LEFT_CONTENT = "left.content"; private static final String RIGHT_CONTENT = "right.content"; - + private final ArrayList leftContent = new ArrayList<>(); + private final ArrayList rightContent = new ArrayList<>(); @Getter private String bannerColor = ""; @Getter @@ -38,21 +40,18 @@ public class BannerConfiguration { @Getter private String bannerDynamic = ""; - private final ArrayList leftContent = new ArrayList<>(); - private final ArrayList rightContent = new ArrayList<>(); - /** * Banner Configuration default constructor. * Verify if the file exist, if it does it will get all the * properties values and save them on the class. * - * @throws IOException the banner level for the web site. + * @throws IOException the banner level for the website. */ public BannerConfiguration() throws IOException { if (!Files.exists(BANNER_PROPERTIES_PATH)) { log.info(String.format( "No file found at %s. Banner will not display.", - BANNER_PROPERTIES_PATH.toString() + BANNER_PROPERTIES_PATH )); return; } @@ -69,8 +68,8 @@ public class BannerConfiguration { /** * This method applies any dynamically configuration found in the properties file, * if it exists. - * @param bannerProps - * @return the banner level for the web site. + * + * @param bannerProps banner props */ private void setBannerProperties(final Properties bannerProps) { @@ -103,10 +102,7 @@ public class BannerConfiguration { * @return if the banner was set. */ public Boolean getHasBanner() { - if (!bannerColor.isEmpty() || !bannerString.isEmpty()) { - return true; - } - return false; + return !bannerColor.isEmpty() || !bannerString.isEmpty(); } /** diff --git a/HIRS_Utils/src/main/java/hirs/utils/HexUtils.java b/HIRS_Utils/src/main/java/hirs/utils/HexUtils.java index 19fbc29d..fc98316e 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/HexUtils.java +++ b/HIRS_Utils/src/main/java/hirs/utils/HexUtils.java @@ -7,22 +7,24 @@ import java.math.BigInteger; */ public final class HexUtils { - /** - * Default private constructor so checkstyles doesn't complain - */ - private HexUtils() { } /** * The mathematical base for the hexadecimal representation. */ public static final int HEX_BASIS = 16; - /** * An integer representation of the byte 0xff or 255. */ public static final int FF_BYTE = 0xff; + /** + * Default private constructor so checkstyles doesn't complain. + */ + private HexUtils() { + } + /** * Converts a binary hex string to a byte array. + * * @param s string to convert * @return byte array representation of s */ @@ -40,6 +42,7 @@ public final class HexUtils { /** * Converts a byte array to a hex represented binary string. + * * @param b byte array to convert * @return hex string representation of array */ @@ -58,6 +61,7 @@ public final class HexUtils { /** * Converts an individual hex string to an integer. + * * @param s an individual hex string * @return an integer representation of a hex string */ @@ -68,9 +72,10 @@ public final class HexUtils { /** * Takes a byte array returns a subset of the array. - * @param b the array to take a subset of + * + * @param b the array to take a subset of * @param start the first index to copy - * @param end the last index to copy (inclusive) + * @param end the last index to copy (inclusive) * @return a new array of bytes from start to end */ public static byte[] subarray(final byte[] b, final int start, final int end) { @@ -81,20 +86,22 @@ public final class HexUtils { /** * Takes in a byte array and reverses the order. - * @param in byte array to reverse + * + * @param in byte array to reverse * @return reversed byte array */ - public static byte[] leReverseByte(final byte[] in) { + public static byte[] leReverseByte(final byte[] in) { byte[] finished = new byte[in.length]; - for (int i = 0; i < finished.length; i++) { - finished[i] = in[(in.length - 1) - i]; - } - return finished; + for (int i = 0; i < finished.length; i++) { + finished[i] = in[(in.length - 1) - i]; + } + return finished; } /** * Takes in a byte array and reverses the order then converts to an int. - * @param in byte array to reverse + * + * @param in byte array to reverse * @return integer that represents the reversed byte array */ public static int leReverseInt(final byte[] in) { @@ -104,12 +111,13 @@ public final class HexUtils { /** * Takes in a byte array of 4 bytes and returns a long. - * @param bytes byte array to convert + * + * @param bytes byte array to convert * @return long representation of the bytes */ public static long bytesToLong(final byte[] bytes) { - BigInteger lValue = new BigInteger(bytes); + BigInteger lValue = new BigInteger(bytes); - return lValue.abs().longValue(); + return lValue.abs().longValue(); } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/JsonUtils.java b/HIRS_Utils/src/main/java/hirs/utils/JsonUtils.java index 3626872e..f166a228 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/JsonUtils.java +++ b/HIRS_Utils/src/main/java/hirs/utils/JsonUtils.java @@ -21,16 +21,17 @@ import java.nio.file.Path; public final class JsonUtils { /** - * Default private constructor so checkstyles doesn't complain + * Default private constructor so checkstyles doesn't complain. */ - private JsonUtils() { } + private JsonUtils() { + } /** * Getter for the JSON Object that is associated with the elementName value * mapped in the associated JSON file. * Default {@link java.nio.charset.Charset} is UTF 8 * - * @param jsonPath the object holding the location of the file to parse. + * @param jsonPath the object holding the location of the file to parse. * @param elementName the specific object to pull from the file * @return a JSON object */ @@ -44,9 +45,9 @@ public final class JsonUtils { * mapped in the associated JSON file. * Default {@link java.nio.charset.Charset} is UTF 8 * - * @param jsonPath the object holding the location of the file to parse. + * @param jsonPath the object holding the location of the file to parse. * @param elementName the specific object to pull from the file - * @param charset the character set to use + * @param charset the character set to use * @return a JSON object */ public static JsonObject getSpecificJsonObject(final Path jsonPath, @@ -77,7 +78,7 @@ public final class JsonUtils { * Getter for the JSON Object that is mapped in the associated JSON file. * * @param jsonPath the object holding the location of the file to parse. - * @param charset the character set to use + * @param charset the character set to use * @return a JSON object */ public static JsonObject getJsonObject(final Path jsonPath, final Charset charset) { @@ -85,7 +86,7 @@ public final class JsonUtils { JsonObject jsonObject = new JsonObject(); if (Files.notExists(jsonPath)) { - log.warn(String.format("No file found at %s.", jsonPath.toString())); + log.warn("No file found at {}.", jsonPath.toString()); } else { try { InputStream inputStream = new FileInputStream(jsonPath.toString()); @@ -106,7 +107,7 @@ public final class JsonUtils { * Default {@link java.nio.charset.Charset} is UTF 8 * * @param jsonFilename the object holding the name of the file in classpath to parse. - * @param elementName the specific object to pull from the file + * @param elementName the specific object to pull from the file * @return a JSON object */ public static JsonObject getSpecificJsonObject(final String jsonFilename, final String elementName) { @@ -120,8 +121,8 @@ public final class JsonUtils { * Default {@link java.nio.charset.Charset} is UTF 8 * * @param jsonFilename the object holding the name of the file in classpath to parse. - * @param elementName the specific object to pull from the file - * @param charset the character set to use + * @param elementName the specific object to pull from the file + * @param charset the character set to use * @return a JSON object */ public static JsonObject getSpecificJsonObject(final String jsonFilename, @@ -152,7 +153,7 @@ public final class JsonUtils { * Getter for the JSON Object that is mapped in the associated JSON file. * * @param jsonFilename the object holding the name of the file in classpath to parse. - * @param charset the character set to use + * @param charset the character set to use * @return a JSON object */ public static JsonObject getJsonObject(final String jsonFilename, final Charset charset) { diff --git a/HIRS_Utils/src/main/java/hirs/utils/PciIds.java b/HIRS_Utils/src/main/java/hirs/utils/PciIds.java index 57751f5e..394008a7 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/PciIds.java +++ b/HIRS_Utils/src/main/java/hirs/utils/PciIds.java @@ -25,29 +25,24 @@ import java.util.List; @Log4j2 public final class PciIds { - /** - * Default private constructor so checkstyles doesn't complain - */ - private PciIds() { } - /** * This pci ids file can be in different places on different distributions. */ public static final List PCI_IDS_PATH = Collections.unmodifiableList(new ArrayList<>() { private static final long serialVersionUID = 1L; + { add("/usr/share/hwdata/pci.ids"); add("/usr/share/misc/pci.ids"); add("/tmp/pci.ids"); } }); - /** * The PCI IDs Database object. - * + *

* This only needs to be loaded one time. - * + *

* The pci ids library protects the data inside the object by making it immutable. */ public static final PciIdsDatabase DB = new PciIdsDatabase(); @@ -65,7 +60,7 @@ public final class PciIds { if (dbFile != null) { InputStream is = null; try { - is = new FileInputStream(new File(dbFile)); + is = new FileInputStream(dbFile); DB.loadStream(is); } catch (IOException e) { // DB will not be ready, hardware IDs will not be translated @@ -83,9 +78,16 @@ public final class PciIds { } } + /** + * Default private constructor so checkstyles doesn't complain. + */ + private PciIds() { + } + /** * Look up the vendor name from the PCI IDs list, if the input string contains an ID. * If any part of this fails, return the original manufacturer value. + * * @param refManufacturer DERUTF8String, likely from a ComponentIdentifier * @return DERUTF8String with the discovered vendor name, or the original manufacturer value. */ @@ -103,6 +105,7 @@ public final class PciIds { /** * Look up the vendor name from the PCI IDs list, if the input string contains an ID. * If any part of this fails, return the original manufacturer value. + * * @param refManufacturer String, likely from a ComponentResult * @return String with the discovered vendor name, or the original manufacturer value. */ @@ -121,8 +124,9 @@ public final class PciIds { * Look up the device name from the PCI IDs list, if the input strings contain IDs. * The Device lookup requires the Vendor ID AND the Device ID to be valid values. * If any part of this fails, return the original model value. + * * @param refManufacturer ASN1UTF8String, likely from a ComponentIdentifier - * @param refModel ASN1UTF8String, likely from a ComponentIdentifier + * @param refModel ASN1UTF8String, likely from a ComponentIdentifier * @return ASN1UTF8String with the discovered device name, or the original model value. */ public static ASN1UTF8String translateDevice(final ASN1UTF8String refManufacturer, @@ -146,8 +150,9 @@ public final class PciIds { * Look up the device name from the PCI IDs list, if the input strings contain IDs. * The Device lookup requires the Vendor ID AND the Device ID to be valid values. * If any part of this fails, return the original model value. + * * @param refManufacturer String, likely from a ComponentResult - * @param refModel String, likely from a ComponentResult + * @param refModel String, likely from a ComponentResult * @return String with the discovered device name, or the original model value. */ public static String translateDevice(final String refManufacturer, @@ -169,24 +174,39 @@ public final class PciIds { /** * Look up the device class name from the PCI IDs list, if the input string contains an ID. * If any part of this fails, return the original manufacturer value. + * * @param refClassCode String, formatted as 2 characters (1 byte) for each of the 3 categories - * Example "010802": - * Class: "01" - * Subclass: "08" - * Programming Interface: "02" + * Example "010802": + * Class: "01" + * Subclass: "08" + * Programming Interface: "02" * @return List 3-element list with the class code - * 1st element: human-readable description of Class - * 2nd element: human-readable description of Subclass - * 3rd element: human-readable description of Programming Interface + * 1st element: human-readable description of Class + * 2nd element: human-readable description of Subclass + * 3rd element: human-readable description of Programming Interface */ public static List translateDeviceClass(final String refClassCode) { List translatedClassCode = new ArrayList<>(); String classCode = refClassCode; if (classCode != null && classCode.trim().matches("^[0-9A-Fa-f]{6}$")) { - String deviceClass = classCode.substring(0, 2).toLowerCase(); - String deviceSubclass = classCode.substring(2, 4).toLowerCase(); - String programInterface = classCode.substring(4, 6).toLowerCase(); + final int startIndexOfDeviceClass = 0; + final int endIndexOfDeviceClass = 2; + String deviceClass = + classCode.substring(startIndexOfDeviceClass, endIndexOfDeviceClass).toLowerCase(); + + final int startIndexOfDeviceSubclass = 2; + final int endIndexOfDeviceSubclass = 4; + String deviceSubclass = + classCode.substring(startIndexOfDeviceSubclass, endIndexOfDeviceSubclass) + .toLowerCase(); + + final int startIndexOfProgramInterface = 4; + final int endIndexOfProgramInterface = 6; + final String programInterface = + classCode.substring(startIndexOfProgramInterface, endIndexOfProgramInterface) + .toLowerCase(); + translatedClassCode.add(deviceClass); translatedClassCode.add(deviceSubclass); translatedClassCode.add(programInterface); diff --git a/HIRS_Utils/src/main/java/hirs/utils/SwidResource.java b/HIRS_Utils/src/main/java/hirs/utils/SwidResource.java index 342dffa7..86267964 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/SwidResource.java +++ b/HIRS_Utils/src/main/java/hirs/utils/SwidResource.java @@ -18,15 +18,31 @@ import java.util.Map; @ToString public class SwidResource { + @Getter + private static final boolean VALID_FILE_SIZE = false; + @Getter @Setter - private String name, size, hashValue; + private String name; + @Getter - private String rimFormat, rimType, rimUriGlobal; -// private TpmWhiteListBaseline tpmWhiteList; + @Setter + private String size; + + @Getter + @Setter + private String hashValue; + + @Getter + private String rimFormat; + + @Getter + private String rimType; + + @Getter + private String rimUriGlobal; + // private TpmWhiteListBaseline tpmWhiteList; private DigestAlgorithm digest = DigestAlgorithm.SHA1; - @Getter - private boolean validFileSize = false; /** * Default constructor. @@ -43,7 +59,7 @@ public class SwidResource { /** * The main constructor that processes a {@code hirs.utils.xjc.File}. * - * @param file {@link File} + * @param file {@link File} * @param digest algorithm associated with pcr values */ public SwidResource(final File file, final DigestAlgorithm digest) { @@ -81,4 +97,4 @@ public class SwidResource { this.digest = digest; // tpmWhiteList = new TpmWhiteListBaseline(this.name); } -} \ No newline at end of file +} diff --git a/HIRS_Utils/src/main/java/hirs/utils/digest/AbstractDigest.java b/HIRS_Utils/src/main/java/hirs/utils/digest/AbstractDigest.java index b843cc36..763ba8f6 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/digest/AbstractDigest.java +++ b/HIRS_Utils/src/main/java/hirs/utils/digest/AbstractDigest.java @@ -15,8 +15,8 @@ import java.util.regex.Pattern; *

* Two classes were made to facilitate persisting them with Hibernate in different ways. * To persist non-nullable entries in an embedded collection, use {@link hirs.utils.digest.Digest} (see - * {@link TPMBaseline} for reference.) To persist nullable entries, use {@link hirs.utils.digest.OptionalDigest} - * (see {@link ImaBlacklistRecord} for reference.) + * {@link TPMBaseline} for reference.) To persist nullable entries, + * use {@link hirs.utils.digest.OptionalDigest} (see {@link ImaBlacklistRecord} for reference.) */ @Log4j2 public abstract class AbstractDigest { @@ -45,30 +45,6 @@ public abstract class AbstractDigest { */ public static final int SHA512_DIGEST_LENGTH = 64; - /** - * Ensures the given algorithm type and digest byte array represent a valid digest. - * This includes ensuring they are both not null or empty and ensuring that the length of the - * digest matches the expected amount of data for the given algorithm. - * - * @param algorithm a digest algorithm - * @param digest the digest computed by this algorithm - * @throws IllegalArgumentException if the provided input does not represent a valid digest - */ - void validateInput(final DigestAlgorithm algorithm, final byte[] digest) - throws IllegalArgumentException { - if (algorithm == null) { - throw new IllegalArgumentException("Algorithm must not be null"); - } - - if (ArrayUtils.isEmpty(digest)) { - throw new IllegalArgumentException("Digest must have at least one byte"); - } - - if (digest.length != algorithm.getLengthInBytes()) { - throw new AbstractDigest.IllegalDigestLength(algorithm, digest); - } - } - /** * This method will help class determine the algorithm associated with the * pcr values given. @@ -114,6 +90,61 @@ public abstract class AbstractDigest { return DigestAlgorithm.UNSPECIFIED; } + /** + * Parses a {@link DigestAlgorithm} from a String returned by {@link AbstractDigest#toString()}. + * + * @param digest the digest string as computed above + * @return the DigestAlgorithm component of the String + */ + static DigestAlgorithm algorithmFromString(final String digest) { + return DigestAlgorithm.findByString(matchString(digest).group(1)); + } + + /** + * Parses a digest from a String returned by {@link AbstractDigest#toString()}. + * + * @param digest the digest string as computed above + * @return the byte array representing the actual digest + */ + static byte[] digestFromString(final String digest) { + return DatatypeConverter.parseHexBinary(matchString(digest).group(2)); + } + + private static Matcher matchString(final String digest) { + Pattern digestPattern = Pattern.compile("(.*) - 0x(.*)"); + Matcher matcher = digestPattern.matcher(digest); + if (!matcher.matches()) { + String message = String.format("String \"%s\" did not match pattern \"%s\"", digest, + digestPattern); + throw new IllegalArgumentException(message); + } + return matcher; + } + + /** + * Ensures the given algorithm type and digest byte array represent a valid digest. + * This includes ensuring they are both not null or empty and ensuring that the length of the + * digest matches the expected amount of data for the given algorithm. + * + * @param algorithm a digest algorithm + * @param digest the digest computed by this algorithm + * @throws IllegalArgumentException if the provided input does not represent a valid digest + */ + void validateInput(final DigestAlgorithm algorithm, final byte[] digest) + throws IllegalArgumentException { + if (algorithm == null) { + throw new IllegalArgumentException("Algorithm must not be null"); + } + + if (ArrayUtils.isEmpty(digest)) { + throw new IllegalArgumentException("Digest must have at least one byte"); + } + + if (digest.length != algorithm.getLengthInBytes()) { + throw new AbstractDigest.IllegalDigestLength(algorithm, digest); + } + } + /** * Retrieves the DigestAlgorithm that identifies which hash * function generated the digest. @@ -140,6 +171,7 @@ public abstract class AbstractDigest { /** * Compares this digest's hash with another digest's hash. + * * @param otherDigest a Digest to compare to. * @return the comparison result type. */ @@ -155,37 +187,6 @@ public abstract class AbstractDigest { return DigestComparisonResultType.MISMATCH; } - /** - * Parses a {@link DigestAlgorithm} from a String returned by {@link AbstractDigest#toString()}. - * - * @param digest the digest string as computed above - * @return the DigestAlgorithm component of the String - */ - static DigestAlgorithm algorithmFromString(final String digest) { - return DigestAlgorithm.findByString(matchString(digest).group(1)); - } - - /** - * Parses a digest from a String returned by {@link AbstractDigest#toString()}. - * - * @param digest the digest string as computed above - * @return the byte array representing the actual digest - */ - static byte[] digestFromString(final String digest) { - return DatatypeConverter.parseHexBinary(matchString(digest).group(2)); - } - - private static Matcher matchString(final String digest) { - Pattern digestPattern = Pattern.compile("(.*) - 0x(.*)"); - Matcher matcher = digestPattern.matcher(digest); - if (!matcher.matches()) { - String message = String.format("String \"%s\" did not match pattern \"%s\"", digest, - digestPattern.toString()); - throw new IllegalArgumentException(message); - } - return matcher; - } - @Override public final int hashCode() { final int prime = 31; @@ -201,21 +202,15 @@ public abstract class AbstractDigest { return true; } - if (obj == null || !(obj instanceof AbstractDigest)) { + if (obj == null || !(obj instanceof AbstractDigest other)) { return false; } - AbstractDigest other = (AbstractDigest) obj; - if (getAlgorithm() != other.getAlgorithm()) { return false; } - if (!Arrays.equals(getDigest(), other.getDigest())) { - return false; - } - - return true; + return Arrays.equals(getDigest(), other.getDigest()); } /** diff --git a/HIRS_Utils/src/main/java/hirs/utils/digest/DigestAlgorithm.java b/HIRS_Utils/src/main/java/hirs/utils/digest/DigestAlgorithm.java index b6b44565..0a67aa98 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/digest/DigestAlgorithm.java +++ b/HIRS_Utils/src/main/java/hirs/utils/digest/DigestAlgorithm.java @@ -50,12 +50,11 @@ public enum DigestAlgorithm { * options for standardAlgorithmName. Throws an IllegalArgumentException if no Enum exists with * that value. * - * @param standardAlgorithmName - * String value of the Enum + * @param standardAlgorithmName String value of the Enum * @return DigestAlgorithm object */ public static DigestAlgorithm findByString(final String standardAlgorithmName) { - for (DigestAlgorithm algorithm: DigestAlgorithm.values()) { + for (DigestAlgorithm algorithm : DigestAlgorithm.values()) { if (algorithm.getStandardAlgorithmName().equals(standardAlgorithmName)) { return algorithm; } @@ -63,4 +62,4 @@ public enum DigestAlgorithm { throw new IllegalArgumentException(String.format("No constant with text \"%s\" found", standardAlgorithmName)); } -} \ No newline at end of file +} diff --git a/HIRS_Utils/src/main/java/hirs/utils/digest/package-info.java b/HIRS_Utils/src/main/java/hirs/utils/digest/package-info.java new file mode 100644 index 00000000..2d2e9eca --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/utils/digest/package-info.java @@ -0,0 +1 @@ +package hirs.utils.digest; diff --git a/HIRS_Utils/src/main/java/hirs/utils/enums/DeviceInfoEnums.java b/HIRS_Utils/src/main/java/hirs/utils/enums/DeviceInfoEnums.java index fef2c9a3..067f7137 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/enums/DeviceInfoEnums.java +++ b/HIRS_Utils/src/main/java/hirs/utils/enums/DeviceInfoEnums.java @@ -2,11 +2,6 @@ package hirs.utils.enums; public final class DeviceInfoEnums { - /** - * Default private constructor so checkstyles doesn't complain - */ - private DeviceInfoEnums() { } - /** * A variable used to describe unavailable hardware, firmware, or OS info. */ @@ -23,4 +18,9 @@ public final class DeviceInfoEnums { * Constant variable representing the various Long sized strings. */ public static final int LONG_STRING_LENGTH = 255; + /** + * Default private constructor so checkstyles doesn't complain. + */ + private DeviceInfoEnums() { + } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/enums/package-info.java b/HIRS_Utils/src/main/java/hirs/utils/enums/package-info.java new file mode 100644 index 00000000..3ff5c9ba --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/utils/enums/package-info.java @@ -0,0 +1 @@ +package hirs.utils.enums; diff --git a/HIRS_Utils/src/main/java/hirs/utils/exception/package-info.java b/HIRS_Utils/src/main/java/hirs/utils/exception/package-info.java new file mode 100644 index 00000000..464dea8c --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/utils/exception/package-info.java @@ -0,0 +1 @@ +package hirs.utils.exception; diff --git a/HIRS_Utils/src/main/java/hirs/utils/package-info.java b/HIRS_Utils/src/main/java/hirs/utils/package-info.java new file mode 100644 index 00000000..361ebc74 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/utils/package-info.java @@ -0,0 +1 @@ +package hirs.utils; diff --git a/HIRS_Utils/src/main/java/hirs/utils/rim/ReferenceManifestValidator.java b/HIRS_Utils/src/main/java/hirs/utils/rim/ReferenceManifestValidator.java index 749c0ab8..c84a70ec 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/rim/ReferenceManifestValidator.java +++ b/HIRS_Utils/src/main/java/hirs/utils/rim/ReferenceManifestValidator.java @@ -5,10 +5,11 @@ import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.UnmarshalException; import jakarta.xml.bind.Unmarshaller; +import lombok.Getter; +import lombok.Setter; import lombok.extern.log4j.Log4j2; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; -import org.bouncycastle.jcajce.provider.asymmetric.X509; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -47,7 +48,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.security.InvalidKeyException; @@ -86,105 +87,29 @@ public class ReferenceManifestValidator { private Document rim; private Unmarshaller unmarshaller; + + @Getter private PublicKey publicKey; + private Schema schema; + + @Getter private String subjectKeyIdentifier; + + @Setter private String rimEventLog; + + @Setter private String trustStoreFile; + + @Setter private List trustStore; - private boolean signatureValid, supportRimValid; - /** - * Setter for the RIM to be validated. The ReferenceManifest object is converted into a - * Document for processing. - * - * @param rimBytes ReferenceManifest object bytes - */ - public void setRim(final byte[] rimBytes) { - try { - Document doc = validateSwidtagSchema(removeXMLWhitespace(new StreamSource( - new ByteArrayInputStream(rimBytes)))); - this.rim = doc; - } catch (IOException e) { - log.error("Error while unmarshalling rim bytes: " + e.getMessage()); - } - } + @Getter + private boolean signatureValid; - /** - * Setter for the swidtag XML to be validated. The XML is passed in via a filepath - * and converted into a Document for processing. - * - * @param path String filepath - */ - public void setRim(final String path) { - File swidtagFile = new File(path); - try { - Document doc = validateSwidtagSchema(removeXMLWhitespace(new StreamSource(swidtagFile))); - this.rim = doc; - } catch (IOException e) { - log.error("Error while unmarshalling rim bytes: " + e.getMessage()); - } - } - - /** - * Getter for signatureValid. - * - * @return true if valid, false if not. - */ - public boolean isSignatureValid() { - return signatureValid; - } - - /** - * Getter for supportRimValid. - * - * @return true if valid, false if not. - */ - public boolean isSupportRimValid() { - return supportRimValid; - } - - /** - * Getter for certificate PublicKey. - * - * @return PublicKey - */ - public PublicKey getPublicKey() { - return publicKey; - } - - /** - * Getter for subjectKeyIdentifier. - * - * @return subjectKeyIdentifier - */ - public String getSubjectKeyIdentifier() { - return subjectKeyIdentifier; - } - - /** - * Setter for the truststore file path. - * @param trustStoreFile the file path to reference - */ - public void setTrustStoreFile(String trustStoreFile) { - this.trustStoreFile = trustStoreFile; - } - - /** - * Setter for truststore - * @param trustStore the List of X509Certificates - */ - public void setTrustStore(List trustStore) { - this.trustStore = trustStore; - } - - /** - * Setter for rimel file path. - * @param rimEventLog the rimel file - */ - public void setRimEventLog(String rimEventLog) { - this.rimEventLog = rimEventLog; - } + @Getter + private boolean supportRimValid; /** * This default constructor creates the Schema object from SCHEMA_URL immediately to save @@ -209,15 +134,47 @@ public class ReferenceManifestValidator { } } + /** + * Setter for the RIM to be validated. The ReferenceManifest object is converted into a + * Document for processing. + * + * @param rimBytes ReferenceManifest object bytes + */ + public void setRim(final byte[] rimBytes) { + try { + Document doc = validateSwidtagSchema(removeXMLWhitespace(new StreamSource( + new ByteArrayInputStream(rimBytes)))); + this.rim = doc; + } catch (IOException e) { + log.error("Error while unmarshalling rim bytes: {}", e.getMessage()); + } + } + + /** + * Setter for the swidtag XML to be validated. The XML is passed in via a filepath + * and converted into a Document for processing. + * + * @param path String filepath + */ + public void setRim(final String path) { + File swidtagFile = new File(path); + try { + Document doc = validateSwidtagSchema(removeXMLWhitespace(new StreamSource(swidtagFile))); + this.rim = doc; + } catch (IOException e) { + log.error("Error while unmarshalling rim bytes: {}", e.getMessage()); + } + } + /** * This method attempts to validate the signature element of the instance's RIM * using a given cert. The cert is compared to either the RIM's embedded certificate * or the RIM's subject key identifier. If the cert is matched then validation proceeds, * otherwise validation ends. * - * @param publicKey public key from the CA credential + * @param publicKey public key from the CA credential * @param subjectKeyIdString string version of the subjet key id of the CA credential - * @param encodedPublicKey the encoded public key + * @param encodedPublicKey the encoded public key * @return true if the signature element is validated, false otherwise */ @SuppressWarnings("magicnumber") @@ -257,7 +214,7 @@ public class ReferenceManifestValidator { return signatureValid; } } catch (IOException e) { - log.warn("Error while parsing certificate data: " + e.getMessage()); + log.warn("Error while parsing certificate data: {}", e.getMessage()); } catch (Exception e) { e.printStackTrace(); } @@ -267,26 +224,27 @@ public class ReferenceManifestValidator { /** * This method validates the rim with a public key cert. + * * @param signingCertPath to the public key certificate used to sign the rim * @return true if both the file element and signature are valid, false otherwise */ - public boolean validateRim(String signingCertPath) { + public boolean validateRim(final String signingCertPath) { Element fileElement = (Element) rim.getElementsByTagNameNS( SwidTagConstants.SWIDTAG_NAMESPACE, "File").item(0); X509Certificate signingCert = parseCertificatesFromPem(signingCertPath).get(0); if (signingCert == null) { return failWithError("Unable to parse the signing cert from " + signingCertPath); } - String subjectKeyIdentifier = ""; + String retrievedSubjectKeyIdentifier = ""; try { - subjectKeyIdentifier = getCertificateSubjectKeyIdentifier(signingCert); + retrievedSubjectKeyIdentifier = getCertificateSubjectKeyIdentifier(signingCert); } catch (IOException e) { return failWithError("Error while parsing SKID: " + e.getMessage()); } boolean isSignatureValid = validateXmlSignature(signingCert.getPublicKey(), - subjectKeyIdentifier, - signingCert.getPublicKey().getEncoded()); + retrievedSubjectKeyIdentifier, + signingCert.getPublicKey().getEncoded()); return isSignatureValid && validateFile(fileElement); } @@ -301,13 +259,15 @@ public class ReferenceManifestValidator { String calculatedHash = getHashValue(input, SHA256); supportRimValid = calculatedHash.equals(expected); if (!supportRimValid) { - log.info("Unmatched support RIM hash! Expected: " + expected - + ", actual: " + calculatedHash); + log.info("Unmatched support RIM hash! Expected: {}, actual: {}", expected, calculatedHash); } } /** - * This method validates a hirs.swid.xjc.File from an indirect payload + * This method validates a hirs.swid.xjc.File from an indirect payload. + * + * @param file file extracted from element + * @return true if the provided file is valid, false otherwise */ private boolean validateFile(final Element file) { String filepath; @@ -317,9 +277,9 @@ public class ReferenceManifestValidator { filepath = file.getAttribute(SwidTagConstants.NAME); } if (getHashValue(filepath, "SHA256").equals( - file.getAttribute(SwidTagConstants._SHA256_HASH.getPrefix() + ":" + - SwidTagConstants._SHA256_HASH.getLocalPart()))) { - log.info("Support RIM hash verified for " + filepath); + file.getAttribute(SwidTagConstants._SHA256_HASH.getPrefix() + ":" + + SwidTagConstants._SHA256_HASH.getLocalPart()))) { + log.info("Support RIM hash verified for {}", filepath); return true; } else { return failWithError("Support RIM hash does not match Base RIM!"); @@ -333,10 +293,10 @@ public class ReferenceManifestValidator { * @return X509Certificate signing cert */ private X509Certificate getCertFromTruststore() throws IOException { - String subjectKeyIdentifier = getKeyName(rim); + String retrievedSubjectKeyIdentifier = getKeyName(rim); for (X509Certificate trustedCert : trustStore) { String trustedSubjectKeyIdentifier = getCertificateSubjectKeyIdentifier(trustedCert); - if (subjectKeyIdentifier.equals(trustedSubjectKeyIdentifier)) { + if (retrievedSubjectKeyIdentifier.equals(trustedSubjectKeyIdentifier)) { return trustedCert; } } @@ -345,10 +305,10 @@ public class ReferenceManifestValidator { } /** - * This method calculates the digest of the file at filepath based on algorithm sha + * This method calculates the digest of the file at filepath based on algorithm sha. * * @param filepath the file to hash - * @param sha the algorithm to use + * @param sha the algorithm to use * @return String digest */ private String getHashValue(final String filepath, final String sha) { @@ -359,11 +319,12 @@ public class ReferenceManifestValidator { } catch (NoSuchAlgorithmException e) { log.warn(e.getMessage()); } catch (IOException e) { - log.warn("Error reading " + filepath + " for hashing: " + e.getMessage()); + log.warn("Error reading {} for hashing: {}", filepath, e.getMessage()); } return null; } + /** * This method calculates the digest of a byte array based on the hashing algorithm passed in. * @@ -401,9 +362,9 @@ public class ReferenceManifestValidator { whySignatureInvalid(signature, context); } } catch (MarshalException e) { - log.warn("Error while unmarshalling XML signature: " + e.getMessage()); + log.warn("Error while unmarshalling XML signature: {}", e.getMessage()); } catch (XMLSignatureException e) { - log.warn("Error while validating XML signature: " + e.getMessage()); + log.warn("Error while validating XML signature: {}", e.getMessage()); } return false; @@ -415,11 +376,11 @@ public class ReferenceManifestValidator { * results are logged. * * @param signature the signature that failed to validate - * @param context the context used for validation + * @param context the context used for validation * @throws XMLSignatureException */ private void whySignatureInvalid(final XMLSignature signature, final DOMValidateContext context) - throws XMLSignatureException{ + throws XMLSignatureException { boolean cryptoValidity = signature.getSignatureValue().validate(context); if (cryptoValidity) { log.error("Signature value is valid."); @@ -435,9 +396,9 @@ public class ReferenceManifestValidator { refUri = "whole document"; } if (refValidity) { - log.error("Reference for " + refUri + " is valid."); + log.error("Reference for {} is valid.", refUri); } else { - log.error("Reference for " + refUri + " is invalid!"); + log.error("Reference for {} is invalid!", refUri); } } } @@ -445,6 +406,7 @@ public class ReferenceManifestValidator { /** * This method validates the cert chain for a given certificate. The truststore is iterated * over until a root CA is found, otherwise an error is returned. + * * @param cert the certificate at the start of the chain * @return true if the chain is valid * @throws Exception if a valid chain is not found in the truststore @@ -462,7 +424,7 @@ public class ReferenceManifestValidator { boolean isChainCertValid; do { isChainCertValid = false; - log.info("Validating " + chainCert.getSubjectX500Principal().getName()); + log.info("Validating {}", chainCert.getSubjectX500Principal().getName()); for (X509Certificate trustedCert : trustStore) { boolean isIssuer = areYouMyIssuer(chainCert, trustedCert); boolean isSigner = areYouMySigner(chainCert, trustedCert); @@ -490,14 +452,15 @@ public class ReferenceManifestValidator { } } while (isChainCertValid); - log.error("CA chain validation failed to validate " - + chainCert.getSubjectX500Principal().getName() + ", " + errorMessage); + log.error("CA chain validation failed to validate {}, {}", + chainCert.getSubjectX500Principal().getName(), errorMessage); return false; } /** * This method checks if cert's issuerDN matches issuer's subjectDN. - * @param cert the signed certificate + * + * @param cert the signed certificate * @param issuer the signing certificate * @return true if they match, false if not * @throws Exception if either argument is null @@ -512,7 +475,8 @@ public class ReferenceManifestValidator { /** * This method checks if cert's issuerDN matches issuer's subjectDN. - * @param cert the signed certificate + * + * @param cert the signed certificate * @param issuer the signing certificate * @return true if they match, false if not * @throws Exception if either argument is null @@ -528,7 +492,8 @@ public class ReferenceManifestValidator { /** * This method checks if cert's signature matches signer's public key. - * @param cert the signed certificate + * + * @param cert the signed certificate * @param signer the signing certificate * @return true if they match * @throws Exception if an error occurs or there is no match @@ -562,6 +527,7 @@ public class ReferenceManifestValidator { /** * This method checks if a given certificate is self signed or not. + * * @param cert the cert to check * @return true if self signed, false if not */ @@ -569,128 +535,6 @@ public class ReferenceManifestValidator { return cert.getIssuerX500Principal().equals(cert.getSubjectX500Principal()); } - /** - * This internal class handles selecting an X509 certificate embedded in a KeyInfo element. - * It is passed as a parameter to a DOMValidateContext that uses it to validate - * an XML signature. - */ - public class X509KeySelector extends KeySelector { - PublicKey publicKey; - X509Certificate signingCert; - /** - * This method selects a public key for validation. - * PKs are parsed preferentially from the following elements: - * - X509Data - * - KeyValue - * The parsed PK is then verified based on the provided algorithm before - * being returned in a KeySelectorResult. - * - * @param keyinfo object containing the cert. - * @param purpose purpose. - * @param algorithm algorithm. - * @param context XMLCryptoContext. - * @return KeySelectorResult holding the PublicKey. - * @throws KeySelectorException exception. - */ - public KeySelectorResult select(final KeyInfo keyinfo, - final KeySelector.Purpose purpose, - final AlgorithmMethod algorithm, - final XMLCryptoContext context) - throws KeySelectorException { - Iterator keyinfoItr = keyinfo.getContent().iterator(); - while (keyinfoItr.hasNext()) { - XMLStructure element = (XMLStructure) keyinfoItr.next(); - if (element instanceof X509Data) { - X509Data data = (X509Data) element; - Iterator dataItr = data.getContent().iterator(); - while (dataItr.hasNext()) { - Object object = dataItr.next(); - if (object instanceof X509Certificate) { - X509Certificate embeddedCert = (X509Certificate) object; - try { - if (isCertChainValid(embeddedCert)) { - publicKey = ((X509Certificate) embeddedCert).getPublicKey(); - signingCert = embeddedCert; - log.info("Certificate chain valid."); - } - } catch (Exception e) { - log.error("Certificate chain invalid: " + e.getMessage()); - } - } - } - } else if (element instanceof KeyValue) { - try { - PublicKey pk = ((KeyValue) element).getPublicKey(); - if (isPublicKeyTrusted(pk)) { - publicKey = pk; - try { - if (isCertChainValid(signingCert)) { - log.info("Certificate chain valid."); - } else { - log.error("Certificate chain invalid."); - } - } catch (Exception e) { - log.error("Certificate chain invalid: " + e.getMessage()); - } - } - } catch (KeyException e) { - log.error("Unable to convert KeyValue data to PK."); - } - } - if (publicKey != null) { - if (areAlgorithmsEqual(algorithm.getAlgorithm(), publicKey.getAlgorithm())) { - return new ReferenceManifestValidator.X509KeySelector - .RIMKeySelectorResult(publicKey); - } - } - } - throw new KeySelectorException("No key found!"); - } - - /** - * This method checks that the signature and public key algorithms match. - * @param uri to match the signature algorithm - * @param name to match the public key algorithm - * @return true if both match, false otherwise - */ - public boolean areAlgorithmsEqual(String uri, String name) { - return uri.equals(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256) - && name.equalsIgnoreCase("RSA"); - } - - /** - * This method compares a public key against those in the truststore. - * @param pk a public key - * @return true if pk is found in the trust store, false otherwise - */ - private boolean isPublicKeyTrusted(final PublicKey pk) { - for (X509Certificate trustedCert : trustStore) { - if (Arrays.equals(trustedCert.getPublicKey().getEncoded(), - pk.getEncoded())) { - signingCert = trustedCert; - return true; - } - } - - return false; - } - - /** - * This internal class creates a KeySelectorResult from the public key. - */ - private static class RIMKeySelectorResult implements KeySelectorResult { - private Key key; - - RIMKeySelectorResult(final Key key) { - this.key = key; - } - - public Key getKey() { - return key; - } - } - } - /** * This method extracts certificate bytes from a string. The bytes are assumed to be * PEM format, and a header and footer are concatenated with the input string to @@ -709,12 +553,10 @@ public class ReferenceManifestValidator { + System.lineSeparator() + pemString + System.lineSeparator() - + certificateFooter).getBytes("UTF-8")); + + certificateFooter).getBytes(StandardCharsets.UTF_8)); return (X509Certificate) factory.generateCertificate(inputStream); } catch (CertificateException e) { - log.warn("Error creating CertificateFactory instance: " + e.getMessage()); - } catch (UnsupportedEncodingException e) { - log.warn("Error while parsing cert from PEM string: " + e.getMessage()); + log.warn("Error creating CertificateFactory instance: {}", e.getMessage()); } return null; @@ -724,11 +566,12 @@ public class ReferenceManifestValidator { * This method returns the X509Certificates found in a PEM file. * Unchecked type case warnings are suppressed because the CertificateFactory * implements X509Certificate objects explicitly. + * * @param filename pem file * @return a list containing all X509Certificates extracted */ @SuppressWarnings("unchecked") - private List parseCertificatesFromPem(String filename) { + private List parseCertificatesFromPem(final String filename) { List certificates = null; FileInputStream fis = null; BufferedInputStream bis = null; @@ -742,14 +585,14 @@ public class ReferenceManifestValidator { (List) certificateFactory.generateCertificates(bis); } - if (certificates.size() < 1) { + if (certificates.isEmpty()) { System.out.println("ERROR: No certificates parsed from " + filename); } bis.close(); } catch (CertificateException e) { - log.error("Error in certificate factory: " + e.getMessage()); + log.error("Error in certificate factory: {}", e.getMessage()); } catch (IOException e) { - log.error("Error reading from input stream: " + e.getMessage()); + log.error("Error reading from input stream: {}", e.getMessage()); } finally { try { if (fis != null) { @@ -759,7 +602,7 @@ public class ReferenceManifestValidator { bis.close(); } } catch (IOException e) { - log.warn("Error closing input stream: " + e.getMessage()); + log.warn("Error closing input stream: {}", e.getMessage()); } } @@ -854,11 +697,135 @@ public class ReferenceManifestValidator { /** * This method logs an error message and returns a false to signal failed validation. + * * @param errorMessage String description of what went wrong * @return false to represent failed validation */ - private boolean failWithError(String errorMessage) { + private boolean failWithError(final String errorMessage) { log.error(errorMessage); return false; } + + /** + * This internal class handles selecting an X509 certificate embedded in a KeyInfo element. + * It is passed as a parameter to a DOMValidateContext that uses it to validate + * an XML signature. + */ + @Setter + @Getter + public class X509KeySelector extends KeySelector { + + private PublicKey publicKey; + private X509Certificate signingCert; + + /** + * This method selects a public key for validation. + * PKs are parsed preferentially from the following elements: + * - X509Data + * - KeyValue + * The parsed PK is then verified based on the provided algorithm before + * being returned in a KeySelectorResult. + * + * @param keyinfo object containing the cert. + * @param purpose purpose. + * @param algorithm algorithm. + * @param context XMLCryptoContext. + * @return KeySelectorResult holding the PublicKey. + * @throws KeySelectorException exception. + */ + public KeySelectorResult select(final KeyInfo keyinfo, + final KeySelector.Purpose purpose, + final AlgorithmMethod algorithm, + final XMLCryptoContext context) + throws KeySelectorException { + Iterator keyinfoItr = keyinfo.getContent().iterator(); + while (keyinfoItr.hasNext()) { + XMLStructure element = (XMLStructure) keyinfoItr.next(); + if (element instanceof X509Data data) { + Iterator dataItr = data.getContent().iterator(); + while (dataItr.hasNext()) { + Object object = dataItr.next(); + if (object instanceof X509Certificate embeddedCert) { + try { + if (isCertChainValid(embeddedCert)) { + publicKey = embeddedCert.getPublicKey(); + signingCert = embeddedCert; + log.info("Certificate chain valid."); + } + } catch (Exception e) { + log.error("Certificate chain invalid: {}", e.getMessage()); + } + } + } + } else if (element instanceof KeyValue) { + try { + PublicKey pk = ((KeyValue) element).getPublicKey(); + if (isPublicKeyTrusted(pk)) { + publicKey = pk; + try { + if (isCertChainValid(signingCert)) { + log.info("Certificate chain valid."); + } else { + log.error("Certificate chain invalid."); + } + } catch (Exception e) { + log.error("Certificate chain invalid: {}", e.getMessage()); + } + } + } catch (KeyException e) { + log.error("Unable to convert KeyValue data to PK."); + } + } + if (publicKey != null) { + if (areAlgorithmsEqual(algorithm.getAlgorithm(), publicKey.getAlgorithm())) { + return new ReferenceManifestValidator.X509KeySelector + .RIMKeySelectorResult(publicKey); + } + } + } + throw new KeySelectorException("No key found!"); + } + + /** + * This method checks that the signature and public key algorithms match. + * + * @param uri to match the signature algorithm + * @param name to match the public key algorithm + * @return true if both match, false otherwise + */ + public boolean areAlgorithmsEqual(final String uri, final String name) { + return uri.equals(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256) + && name.equalsIgnoreCase("RSA"); + } + + /** + * This method compares a public key against those in the truststore. + * + * @param pk a public key + * @return true if pk is found in the trust store, false otherwise + */ + private boolean isPublicKeyTrusted(final PublicKey pk) { + for (X509Certificate trustedCert : trustStore) { + if (Arrays.equals(trustedCert.getPublicKey().getEncoded(), + pk.getEncoded())) { + signingCert = trustedCert; + return true; + } + } + + return false; + } + + /** + * This internal class creates a KeySelectorResult from the public key. + */ + @Getter + private static class RIMKeySelectorResult implements KeySelectorResult { + private final Key key; + + RIMKeySelectorResult(final Key key) { + this.key = key; + } + } + } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/rim/package-info.java b/HIRS_Utils/src/main/java/hirs/utils/rim/package-info.java new file mode 100644 index 00000000..e72d99d1 --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/utils/rim/package-info.java @@ -0,0 +1 @@ +package hirs.utils.rim; diff --git a/HIRS_Utils/src/main/java/hirs/utils/swid/SwidTagConstants.java b/HIRS_Utils/src/main/java/hirs/utils/swid/SwidTagConstants.java index 89ea5581..af58a8bc 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/swid/SwidTagConstants.java +++ b/HIRS_Utils/src/main/java/hirs/utils/swid/SwidTagConstants.java @@ -8,26 +8,19 @@ import javax.xml.namespace.QName; * class. It is expected that member properties of this class will expand as * more functionality is added to SwidTagGateway. */ -public class SwidTagConstants { +public final class SwidTagConstants { - /** - * Default private constructor so checkstyles doesn't complain - */ - private SwidTagConstants() { } - - public static final String DEFAULT_KEYSTORE_FILE = "keystore.jks";//"/opt/hirs/rimtool/keystore.jks"; + public static final String DEFAULT_KEYSTORE_FILE = "keystore.jks"; //"/opt/hirs/rimtool/keystore.jks"; public static final String DEFAULT_KEYSTORE_PASSWORD = "password"; public static final String DEFAULT_PRIVATE_KEY_ALIAS = "1"; public static final String DEFAULT_ATTRIBUTES_FILE = "/opt/hirs/rimtool/rim_fields.json"; public static final String DEFAULT_ENGLISH = "en"; - - 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_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 SWIDTAG_NAMESPACE = "http://standards.iso.org/iso/19770/-2/2015/schema.xsd"; - public static final String SOFTWARE_IDENTITY = "SoftwareIdentity"; public static final String ENTITY = "Entity"; public static final String LINK = "Link"; @@ -76,48 +69,43 @@ public class SwidTagConstants { public static final String SUPPORT_RIM_FORMAT_MISSING = "supportRIMFormat missing"; public static final String SUPPORT_RIM_URI_GLOBAL = "supportRIMURIGlobal"; public static final String DATETIME = "dateTime"; - public static final String NIST_NS = "http://csrc.nist.gov/ns/swid/2015-extensions/1.0"; public static final String TCG_NS = "https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model"; public static final String RFC3852_NS = "https://www.ietf.org/rfc/rfc3852.txt"; public static final String RFC3339_NS = "https://www.ietf.org/rfc/rfc3339.txt"; - public static final String N8060_PFX = "n8060"; public static final String RIM_PFX = "rim"; public static final String FX_SEPARATOR = ":"; public static final String RFC3852_PFX = "rcf3852"; public static final String RFC3339_PFX = "rcf3339"; - - public static final String _COLLOQUIAL_VERSION_STR = N8060_PFX + FX_SEPARATOR + - COLLOQUIAL_VERSION; - public static final String _PRODUCT_STR = N8060_PFX + FX_SEPARATOR + - PRODUCT; - public static final String _REVISION_STR = N8060_PFX + FX_SEPARATOR + - REVISION; - public static final String _EDITION_STR = N8060_PFX + FX_SEPARATOR + - EDITION; - public static final String _RIM_LINK_HASH_STR = RIM_PFX + FX_SEPARATOR + - RIM_LINK_HASH; - public static final String _BINDING_SPEC_STR = RIM_PFX + FX_SEPARATOR + - BINDING_SPEC; - public static final String _BINDING_SPEC_VERSION_STR = RIM_PFX + FX_SEPARATOR + - BINDING_SPEC_VERSION; - public static final String _PLATFORM_MANUFACTURER_STR = RIM_PFX + FX_SEPARATOR + - PLATFORM_MANUFACTURER_STR; - public static final String _PLATFORM_MANUFACTURER_ID_STR = RIM_PFX + FX_SEPARATOR + - PLATFORM_MANUFACTURER_ID; - public static final String _PLATFORM_MODEL_STR = RIM_PFX + FX_SEPARATOR + - PLATFORM_MODEL; - public static final String _PLATFORM_VERSION_STR = RIM_PFX + FX_SEPARATOR + - PLATFORM_VERSION; - public static final String _PAYLOAD_TYPE_STR = RIM_PFX + FX_SEPARATOR + - PAYLOAD_TYPE; - public static final String _PC_URI_LOCAL_STR = RIM_PFX + FX_SEPARATOR + - PC_URI_LOCAL; - public static final String _PC_URI_GLOBAL_STR = RIM_PFX + FX_SEPARATOR + - PC_URI_GLOBAL; - - + public static final String _COLLOQUIAL_VERSION_STR = N8060_PFX + FX_SEPARATOR + + COLLOQUIAL_VERSION; + public static final String _PRODUCT_STR = N8060_PFX + FX_SEPARATOR + + PRODUCT; + public static final String _REVISION_STR = N8060_PFX + FX_SEPARATOR + + REVISION; + public static final String _EDITION_STR = N8060_PFX + FX_SEPARATOR + + EDITION; + public static final String _RIM_LINK_HASH_STR = RIM_PFX + FX_SEPARATOR + + RIM_LINK_HASH; + public static final String _BINDING_SPEC_STR = RIM_PFX + FX_SEPARATOR + + BINDING_SPEC; + public static final String _BINDING_SPEC_VERSION_STR = RIM_PFX + FX_SEPARATOR + + BINDING_SPEC_VERSION; + public static final String _PLATFORM_MANUFACTURER_STR = RIM_PFX + FX_SEPARATOR + + PLATFORM_MANUFACTURER_STR; + public static final String _PLATFORM_MANUFACTURER_ID_STR = RIM_PFX + FX_SEPARATOR + + PLATFORM_MANUFACTURER_ID; + public static final String _PLATFORM_MODEL_STR = RIM_PFX + FX_SEPARATOR + + PLATFORM_MODEL; + public static final String _PLATFORM_VERSION_STR = RIM_PFX + FX_SEPARATOR + + PLATFORM_VERSION; + public static final String _PAYLOAD_TYPE_STR = RIM_PFX + FX_SEPARATOR + + PAYLOAD_TYPE; + public static final String _PC_URI_LOCAL_STR = RIM_PFX + FX_SEPARATOR + + PC_URI_LOCAL; + public static final String _PC_URI_GLOBAL_STR = RIM_PFX + FX_SEPARATOR + + PC_URI_GLOBAL; public static final QName _SHA256_HASH = new QName( "http://www.w3.org/2001/04/xmlenc#sha256", HASH, "SHA256"); public static final QName _COLLOQUIAL_VERSION = new QName( @@ -168,6 +156,11 @@ public class SwidTagConstants { NIST_NS, "envVarSuffix", N8060_PFX); public static final QName _N8060_PATHSEPARATOR = new QName( NIST_NS, "pathSeparator", N8060_PFX); - public static final String CA_ISSUERS = "1.3.6.1.5.5.7.48.2"; + + /** + * Default private constructor so checkstyles doesn't complain. + */ + private SwidTagConstants() { + } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/swid/package-info.java b/HIRS_Utils/src/main/java/hirs/utils/swid/package-info.java new file mode 100644 index 00000000..91c5a00f --- /dev/null +++ b/HIRS_Utils/src/main/java/hirs/utils/swid/package-info.java @@ -0,0 +1 @@ +package hirs.utils.swid; diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java index 9d02ea47..587b963e 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader.java @@ -13,18 +13,18 @@ import java.io.IOException; * Class to process the DEVICE_SECURITY_EVENT_DATA_HEADER. * DEVICE_SECURITY_EVENT_DATA_HEADER contains the measurement(s) and hash algorithm identifier * returned by the SPDM "GET_MEASUREMENTS" function. - * + *

* HEADERS defined by PFP v1.06 Rev 52: *

* typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER { - * UINT8 Signature[16]; - * UINT16 Version; - * UINT16 Length; - * UINT32 SpdmHashAlg; - * UINT32 DeviceType; - * SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock; - * UINT64 DevicePathLength; - * UNIT8 DevicePath[DevicePathLength] + * UINT8 Signature[16]; + * UINT16 Version; + * UINT16 Length; + * UINT32 SpdmHashAlg; + * UINT32 DeviceType; + * SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock; + * UINT64 DevicePathLength; + * UNIT8 DevicePath[DevicePathLength] * } DEVICE_SECURITY_EVENT_DATA_HEADER; *

* Assumption: there is only 1 SpdmMeasurementBlock per event. Need more test patterns to verify. @@ -62,8 +62,9 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventHeader { super(dsedBytes); + final int dsedBytesSrcIndex1 = 18; byte[] lengthBytes = new byte[UefiConstants.SIZE_2]; - System.arraycopy(dsedBytes, 18, lengthBytes, 0, + System.arraycopy(dsedBytes, dsedBytesSrcIndex1, lengthBytes, 0, UefiConstants.SIZE_2); length = HexUtils.leReverseInt(lengthBytes); @@ -72,18 +73,22 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventHeader { UefiConstants.SIZE_4); spdmHashAlgo = HexUtils.leReverseInt(spdmHashAlgoBytes); - extractDeviceType(dsedBytes, 24); + final int dsedBytesStartByte = 24; + extractDeviceType(dsedBytes, dsedBytesStartByte); // get the size of the SPDM Measurement Block + final int dsedBytesSrcIndex2 = 30; byte[] sizeOfSpdmMeasBlockBytes = new byte[UefiConstants.SIZE_2]; - System.arraycopy(dsedBytes, 30, sizeOfSpdmMeasBlockBytes, 0, + System.arraycopy(dsedBytes, dsedBytesSrcIndex2, sizeOfSpdmMeasBlockBytes, 0, UefiConstants.SIZE_2); - int sizeOfSpdmMeas = HexUtils.leReverseInt(sizeOfSpdmMeasBlockBytes); - int sizeOfSpdmMeasBlock = sizeOfSpdmMeas + 4; // header is 4 bytes + final int sizeOfSpdmMeas = HexUtils.leReverseInt(sizeOfSpdmMeasBlockBytes); + final int offSetBytesForSpdm = 4; + final int sizeOfSpdmMeasBlock = sizeOfSpdmMeas + offSetBytesForSpdm; // header is 4 bytes // extract the bytes that comprise the SPDM Measurement Block + final int dsedBytesSrcIndex3 = 28; byte[] spdmMeasBlockBytes = new byte[sizeOfSpdmMeasBlock]; - System.arraycopy(dsedBytes, 28, spdmMeasBlockBytes, 0, + System.arraycopy(dsedBytes, dsedBytesSrcIndex3, spdmMeasBlockBytes, 0, sizeOfSpdmMeasBlock); ByteArrayInputStream spdmMeasurementBlockData = @@ -96,7 +101,8 @@ public class DeviceSecurityEventDataHeader extends DeviceSecurityEventHeader { spdmMeasurementBlockInfo = " Error reading SPDM Measurement Block"; } - int devPathLenStartByte = 28 + sizeOfSpdmMeasBlock; + final int offSetBytesForDevPath = 28; + final int devPathLenStartByte = offSetBytesForDevPath + sizeOfSpdmMeasBlock; extractDevicePathAndFinalSize(dsedBytes, devPathLenStartByte); } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader2.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader2.java index 6c402afd..55ec9c06 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader2.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataHeader2.java @@ -7,26 +7,52 @@ import lombok.Getter; * Class to process the DEVICE_SECURITY_EVENT_DATA_HEADER2. * DEVICE_SECURITY_EVENT_DATA_HEADER2 contains the measurement(s) and hash algorithm identifier * returned by the SPDM "GET_MEASUREMENTS" function. - * + *

* HEADERS defined by PFP v1.06 Rev 52: *

* typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER2 { - * UINT8 Signature[16]; - * UINT16 Version; - * UINT8 AuthState; - * UINT8 Reserved - * UINT32 Length; - * UINT32 DeviceType; - * UINT32 SubHeaderType; - * UINT32 SubHeaderLength; - * UINT64 SubHeaderUID; - * UINT64 DevicePathLength; - * UNIT8 DevicePath[DevicePathLength] + * UINT8 Signature[16]; + * UINT16 Version; + * UINT8 AuthState; + * UINT8 Reserved + * UINT32 Length; + * UINT32 DeviceType; + * UINT32 SubHeaderType; + * UINT32 SubHeaderLength; + * UINT64 SubHeaderUID; + * UINT64 DevicePathLength; + * UNIT8 DevicePath[DevicePathLength] * } DEVICE_SECURITY_EVENT_DATA_HEADER2; *

*/ public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader { + /** + * Auth state - success. + */ + public static final int AUTH_SUCCESS = 0; + /** + * Auth state - digital signature of the data is valid, but the public key certificate chain is not + * validated with the entry in the UEFI device signature variable. + */ + public static final int AUTH_NO_AUTHORITY = 1; + /** + * Auth state - digital signature of the measurement data is valid, but the reported device capabilities, + * negotiated parameters or certificate chains were not validated by a transcript. + */ + public static final int AUTH_NO_BINDING = 2; + /** + * Auth state - data has no digital signature. + */ + public static final int AUTH_FAIL_NO_SIG = 3; + /** + * Auth state - data is invalid. + */ + public static final int AUTH_FAIL_INVALID = 4; + /** + * Auth state - device is not an SPDM-capable device. + */ + public static final int AUTH_NO_SPDM = 0xFF; /** * Event auth state. */ @@ -55,33 +81,6 @@ public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader { @Getter private String subHeaderUid = ""; - /** - * Auth state - success. - */ - public static final int AUTH_SUCCESS = 0; - /** - * Auth state - digital signature of the data is valid, but the public key certificate chain is not - * validated with the entry in the UEFI device signature variable. - */ - public static final int AUTH_NO_AUTHORITY = 1; - /** - * Auth state - digital signature of the measurement data is valid, but the reported device capabilities, - * negotiated parameters or certificate chains were not validated by a transcript. - */ - public static final int AUTH_NO_BINDING = 2; - /** - * Auth state - data has no digital signature. - */ - public static final int AUTH_FAIL_NO_SIG = 3; - /** - * Auth state - data is invalid. - */ - public static final int AUTH_FAIL_INVALID = 4; - /** - * Auth state - device is not an SPDM-capable device. - */ - public static final int AUTH_NO_SPDM = 0xFF; - /** * DeviceSecurityEventDataHeader2 Constructor. * @@ -91,33 +90,43 @@ public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader { super(dsedBytes); + final int dsedBytesSrcIndex = 18; byte[] authStateBytes = new byte[1]; - System.arraycopy(dsedBytes, 18, authStateBytes, 0, 1); + System.arraycopy(dsedBytes, dsedBytesSrcIndex, authStateBytes, 0, 1); authState = HexUtils.leReverseInt(authStateBytes); // byte[] reserved[Bytes]: 1 byte - byte[] lengthBytes = new byte[4]; - System.arraycopy(dsedBytes, 20, lengthBytes, 0, 4); + final int dsedBytesSrcIndex2 = 20; + final int lengthBytesSize = 4; + byte[] lengthBytes = new byte[lengthBytesSize]; + System.arraycopy(dsedBytes, dsedBytesSrcIndex2, lengthBytes, 0, lengthBytesSize); length = HexUtils.leReverseInt(lengthBytes); - extractDeviceType(dsedBytes, 24); + final int dsedBytesStartByte1 = 24; + extractDeviceType(dsedBytes, dsedBytesStartByte1); - byte[] subHeaderTypeBytes = new byte[4]; - System.arraycopy(dsedBytes, 28, subHeaderTypeBytes, 0, 4); + final int dsedBytesSrcIndex3 = 28; + final int subHeaderTypeBytesSize = 4; + byte[] subHeaderTypeBytes = new byte[subHeaderTypeBytesSize]; + System.arraycopy(dsedBytes, dsedBytesSrcIndex3, subHeaderTypeBytes, 0, subHeaderTypeBytesSize); subHeaderType = HexUtils.leReverseInt(subHeaderTypeBytes); - byte[] subHeaderLengthBytes = new byte[4]; - System.arraycopy(dsedBytes, 32, subHeaderLengthBytes, 0, 4); + final int dsedBytesSrcIndex4 = 32; + final int subHeaderLengthBytesSize = 4; + byte[] subHeaderLengthBytes = new byte[subHeaderLengthBytesSize]; + System.arraycopy(dsedBytes, dsedBytesSrcIndex4, subHeaderLengthBytes, 0, subHeaderLengthBytesSize); subHeaderLength = HexUtils.leReverseInt(subHeaderLengthBytes); - byte[] subHeaderUidBytes = new byte[8]; - System.arraycopy(dsedBytes, 36, subHeaderUidBytes, 0, 8); + final int dsedBytesSrcIndex5 = 36; + final int subHeaderUidBytesSize = 8; + byte[] subHeaderUidBytes = new byte[subHeaderUidBytesSize]; + System.arraycopy(dsedBytes, dsedBytesSrcIndex5, subHeaderUidBytes, 0, subHeaderUidBytesSize); subHeaderUidBytes = HexUtils.leReverseByte(subHeaderUidBytes); subHeaderUid = HexUtils.byteArrayToHexString(subHeaderUidBytes); - int devPathLenStartByte = 44; - extractDevicePathAndFinalSize(dsedBytes, devPathLenStartByte); + final int dsedBytesStartByte2 = 44; + extractDevicePathAndFinalSize(dsedBytes, dsedBytesStartByte2); } /** @@ -139,22 +148,14 @@ public class DeviceSecurityEventDataHeader2 extends DeviceSecurityEventHeader { * @return a description of the auth state. */ public String getAuthStateString() { - - switch (authState) { - case AUTH_SUCCESS: - return ("AUTH_SUCCESS"); - case AUTH_NO_AUTHORITY: - return ("AUTH_NO_AUTHORITY"); - case AUTH_NO_BINDING: - return ("AUTH_NO_BINDING"); - case AUTH_FAIL_NO_SIG: - return ("AUTH_FAIL_NO_SIG"); - case AUTH_FAIL_INVALID: - return ("AUTH_FAIL_INVALID"); - case AUTH_NO_SPDM: - return ("AUTH_NO_SPDM"); - default: - return ("Auth State unknown"); - } + return switch (authState) { + case AUTH_SUCCESS -> ("AUTH_SUCCESS"); + case AUTH_NO_AUTHORITY -> ("AUTH_NO_AUTHORITY"); + case AUTH_NO_BINDING -> ("AUTH_NO_BINDING"); + case AUTH_FAIL_NO_SIG -> ("AUTH_FAIL_NO_SIG"); + case AUTH_FAIL_INVALID -> ("AUTH_FAIL_INVALID"); + case AUTH_NO_SPDM -> ("AUTH_NO_SPDM"); + default -> ("Auth State unknown"); + }; } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataPciContext.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataPciContext.java index fda1397c..05073d41 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataPciContext.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataPciContext.java @@ -13,27 +13,27 @@ import static hirs.utils.PciIds.translateVendor; * Class to process the DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT event per PFP. *

* typedef struct tdDEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT { - * UINT16 Version; - * UINT16 Length; - * UINT16 VendorId; - * UINT16 DeviceId; - * UINT16 RevisionId; - * UINT16 ClassCode[3]; - * UINT16 SubsystemVendorId; - * UINT16 SubsystemId; + * UINT16 Version; + * UINT16 Length; + * UINT16 VendorId; + * UINT16 DeviceId; + * UINT16 RevisionId; + * UINT16 ClassCode[3]; + * UINT16 SubsystemVendorId; + * UINT16 SubsystemId; *

* The following fields are defined by the PCI Express Base Specification rev4.0 v1.0. - * VendorId - * DeviceId - * RevisionId - * ClassCode - * SubsystemVendorId - * SubsystemId + * VendorId + * DeviceId + * RevisionId + * ClassCode + * SubsystemVendorId + * SubsystemId * Vendor id and device id are registered to specific manufacturers. - * https://admin.pci-ids.ucw.cz/read/PC/ - * Ex. vendor id 8086 and device id 0b60: https://admin.pci-ids.ucw.cz/read/PC/8086/0b60 + * https://admin.pci-ids.ucw.cz/read/PC/ + * Ex. vendor id 8086 and device id 0b60: https://admin.pci-ids.ucw.cz/read/PC/8086/0b60 * Class code can be looked up on the web. - * https://admin.pci-ids.ucw.cz/read/PD/ + * https://admin.pci-ids.ucw.cz/read/PD/ * The revision ID is controlled by the vendor and cannot be looked up. */ public class DeviceSecurityEventDataPciContext extends DeviceSecurityEventDataDeviceContext { @@ -78,28 +78,36 @@ public class DeviceSecurityEventDataPciContext extends DeviceSecurityEventDataDe super(dSEDpciContextBytes); + final int dSEDpciContextBytesSrcIndex1 = 4; byte[] pciVendorIdBytes = new byte[2]; - System.arraycopy(dSEDpciContextBytes, 4, pciVendorIdBytes, 0, 2); + System.arraycopy(dSEDpciContextBytes, dSEDpciContextBytesSrcIndex1, pciVendorIdBytes, 0, 2); vendorId = HexUtils.byteArrayToHexString(HexUtils.leReverseByte(pciVendorIdBytes)); + final int dSEDpciContextBytesSrcIndex2 = 6; byte[] pciDeviceIdBytes = new byte[2]; - System.arraycopy(dSEDpciContextBytes, 6, pciDeviceIdBytes, 0, 2); + System.arraycopy(dSEDpciContextBytes, dSEDpciContextBytesSrcIndex2, pciDeviceIdBytes, 0, 2); deviceId = HexUtils.byteArrayToHexString(HexUtils.leReverseByte(pciDeviceIdBytes)); + final int dSEDpciContextBytesSrcIndex3 = 8; byte[] pciRevisionIdBytes = new byte[1]; - System.arraycopy(dSEDpciContextBytes, 8, pciRevisionIdBytes, 0, 1); + System.arraycopy(dSEDpciContextBytes, dSEDpciContextBytesSrcIndex3, pciRevisionIdBytes, 0, 1); revisionId = HexUtils.byteArrayToHexString(HexUtils.leReverseByte(pciRevisionIdBytes)); - byte[] pciClassCodeBytes = new byte[3]; - System.arraycopy(dSEDpciContextBytes, 9, pciClassCodeBytes, 0, 3); + final int dSEDpciContextBytesSrcIndex4 = 9; + final int pciClassCodeBytesSize = 3; + byte[] pciClassCodeBytes = new byte[pciClassCodeBytesSize]; + System.arraycopy(dSEDpciContextBytes, dSEDpciContextBytesSrcIndex4, pciClassCodeBytes, 0, + pciClassCodeBytesSize); classCode = HexUtils.byteArrayToHexString(HexUtils.leReverseByte(pciClassCodeBytes)); + final int dSEDpciContextBytesSrcIndex5 = 12; byte[] pciSubsystemVendorIdBytes = new byte[2]; - System.arraycopy(dSEDpciContextBytes, 12, pciSubsystemVendorIdBytes, 0, 2); + System.arraycopy(dSEDpciContextBytes, dSEDpciContextBytesSrcIndex5, pciSubsystemVendorIdBytes, 0, 2); subsystemVendorId = HexUtils.byteArrayToHexString(HexUtils.leReverseByte(pciSubsystemVendorIdBytes)); + final int dSEDpciContextBytesSrcIndex6 = 14; byte[] pciSubsystemIdBytes = new byte[2]; - System.arraycopy(dSEDpciContextBytes, 14, pciSubsystemIdBytes, 0, 2); + System.arraycopy(dSEDpciContextBytes, dSEDpciContextBytesSrcIndex6, pciSubsystemIdBytes, 0, 2); subsystemId = HexUtils.byteArrayToHexString(HexUtils.leReverseByte(pciSubsystemIdBytes)); } @@ -118,8 +126,9 @@ public class DeviceSecurityEventDataPciContext extends DeviceSecurityEventDataDe dSEDpciContextInfo += " RevisionID = " + revisionId + "\n"; List classCodeList = translateDeviceClass(classCode); + final int validClassCodeListSize = 3; dSEDpciContextInfo += " Device Class: \n"; - if (classCodeList.size() == 3) { + if (classCodeList.size() == validClassCodeListSize) { dSEDpciContextInfo += " Class = " + classCodeList.get(0) + "\n"; dSEDpciContextInfo += " Subclass = " + classCodeList.get(1) + "\n"; dSEDpciContextInfo += " Programming Interface = " + classCodeList.get(2) + "\n"; diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderCertChain.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderCertChain.java index 727883ec..a6c752e9 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderCertChain.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderCertChain.java @@ -9,11 +9,11 @@ import hirs.utils.tpm.eventlog.spdm.SpdmHa; * *

* typedef union tdDEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN { - * UINT16 SpdmVersion; - * UINT8 SpdmSlotId; - * UINT8 Reserved; - * UINT32 SpdmBaseHashAlgo; - * SPDM_CERT_CHAIN SpdmCertChain; + * UINT16 SpdmVersion; + * UINT8 SpdmSlotId; + * UINT8 Reserved; + * UINT32 SpdmBaseHashAlgo; + * SPDM_CERT_CHAIN SpdmCertChain; * } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN; *

* SpdmVersion: SpdmBaseHashAlgo @@ -61,16 +61,21 @@ public class DeviceSecurityEventDataSubHeaderCertChain extends DeviceSecurityEve // byte[] reserved[Bytes]: 1 byte - byte[] spdmBaseHashAlgoBytes = new byte[4]; - System.arraycopy(dsedSubHBytes, 4, spdmBaseHashAlgoBytes, 0, 4); + final int dsedSybHBytesSrcIndex1 = 4; + final int spdmBaseHashAlgoBytesSize = 4; + byte[] spdmBaseHashAlgoBytes = new byte[spdmBaseHashAlgoBytesSize]; + System.arraycopy(dsedSubHBytes, dsedSybHBytesSrcIndex1, spdmBaseHashAlgoBytes, 0, + spdmBaseHashAlgoBytesSize); spdmBaseHashAlgo = HexUtils.leReverseInt(spdmBaseHashAlgoBytes); // get the size of the SPDM Cert Chain - int spdmCertChainSize = dsedSubHBytes.length - 8; + final int offsetForSpdmCertChain = 8; + int spdmCertChainSize = dsedSubHBytes.length - offsetForSpdmCertChain; // extract the bytes that comprise the SPDM Cert Chain + final int dsedSybHBytesSrcIndex2 = 8; byte[] spdmCertChainBytes = new byte[spdmCertChainSize]; - System.arraycopy(dsedSubHBytes, 8, spdmCertChainBytes, 0, + System.arraycopy(dsedSubHBytes, dsedSybHBytesSrcIndex2, spdmCertChainBytes, 0, spdmCertChainSize); int spdmBaseHashAlgoSize = SpdmHa.tcgAlgIdToByteSize(spdmBaseHashAlgo); diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.java index c13c2251..c4cf4659 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock.java @@ -15,24 +15,28 @@ import java.util.List; * *

* typedef union tdDEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK { - * UINT16 SpdmVersion; - * UINT8 SpdmMeasurementBlockCount; - * UINT8 Reserved; - * UINT32 SpdmMeasurementHashAlgo; - * SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock[SpdmMeasurementBlockCount]; + * UINT16 SpdmVersion; + * UINT8 SpdmMeasurementBlockCount; + * UINT8 Reserved; + * UINT32 SpdmMeasurementHashAlgo; + * SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock[SpdmMeasurementBlockCount]; * } DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK; *

- * + *

* SpdmMeasurementBlock is an array of SPDM_MEASUREMENT_BLOCKs - * The size of each block is the same and can be found by either: - * 1) 4 + SpdmMeasurementBlock MeasurementSize - * OR - * 2) 4 + hash length of the hash algorithm found in - * DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK SpdmMeasurementHashAlgo - * where 4 is the size of the SpdmMeasurementBlock header + * The size of each block is the same and can be found by either: + * 1) 4 + SpdmMeasurementBlock MeasurementSize + * OR + * 2) 4 + hash length of the hash algorithm found in + * DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK SpdmMeasurementHashAlgo + * where 4 is the size of the SpdmMeasurementBlock header */ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends DeviceSecurityEventDataSubHeader { + /** + * List of SPDM Measurement Blocks. + */ + private final List spdmMeasurementBlockList; /** * SPDM version. */ @@ -48,11 +52,6 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device */ @Getter private int spdmMeasurementHashAlgo = -1; - - /** - * List of SPDM Measurement Blocks. - */ - private List spdmMeasurementBlockList; /** * Error reading SPDM Measurement Block. */ @@ -77,16 +76,21 @@ public class DeviceSecurityEventDataSubHeaderSpdmMeasurementBlock extends Device // byte[] reserved[Bytes]: 1 byte - byte[] spdmMeasurementHashAlgoBytes = new byte[4]; - System.arraycopy(dsedSubHBytes, 4, spdmMeasurementHashAlgoBytes, 0, 4); + final int spdmMeasurementHashAlgoBytesSize = 4; + final int dsedSubHBytesSrcIndex1 = 4; + byte[] spdmMeasurementHashAlgoBytes = new byte[spdmMeasurementHashAlgoBytesSize]; + System.arraycopy(dsedSubHBytes, dsedSubHBytesSrcIndex1, spdmMeasurementHashAlgoBytes, 0, + spdmMeasurementHashAlgoBytesSize); spdmMeasurementHashAlgo = HexUtils.leReverseInt(spdmMeasurementHashAlgoBytes); // get the total size of the SPDM Measurement Block List - int spdmMeasurementBlockListSize = dsedSubHBytes.length - 8; + final int offsetForspdmMeasurementBlockList = 8; + final int spdmMeasurementBlockListSize = dsedSubHBytes.length - offsetForspdmMeasurementBlockList; // extract the bytes that comprise the SPDM Measurement Block List + final int dsedSubHBytesSrcIndex2 = 8; byte[] spdmMeasurementBlockListBytes = new byte[spdmMeasurementBlockListSize]; - System.arraycopy(dsedSubHBytes, 8, spdmMeasurementBlockListBytes, 0, + System.arraycopy(dsedSubHBytes, dsedSubHBytesSrcIndex2, spdmMeasurementBlockListBytes, 0, spdmMeasurementBlockListSize); ByteArrayInputStream spdmMeasurementBlockListData = diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventHeader.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventHeader.java index 13612538..68d6ea98 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventHeader.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/DeviceSecurityEventHeader.java @@ -12,51 +12,55 @@ import java.nio.charset.StandardCharsets; * The first 16 bytes of the event data header MUST be a String based identifier (Signature), * NUL-terminated, per PFP. The only currently defined Signature is "SPDM Device Sec", * which implies the data is a DEVICE_SECURITY_EVENT_DATA or ..DATA2. - * + *

* HEADERS defined by PFP v1.06 Rev 52. * Certain fields are common to both ..HEADER and ..HEADER2, and are noted below the structures. *

* typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER { - * UINT8 Signature[16]; - * UINT16 Version; - * UINT16 Length; - * UINT32 SpdmHashAlg; - * UINT32 DeviceType; - * SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock; - * UINT64 DevicePathLength; - * UNIT8 DevicePath[DevicePathLength] + * UINT8 Signature[16]; + * UINT16 Version; + * UINT16 Length; + * UINT32 SpdmHashAlg; + * UINT32 DeviceType; + * SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock; + * UINT64 DevicePathLength; + * UNIT8 DevicePath[DevicePathLength] * } DEVICE_SECURITY_EVENT_DATA_HEADER; *

* typedef struct tdDEVICE_SECURITY_EVENT_DATA_HEADER2 { - NOT IMPLEMENTED YET - * UINT8 Signature[16]; - * UINT16 Version; - * UINT8 AuthState; - * UINT8 Reserved; - * UINT32 Length; - * UINT32 DeviceType; - * UINT32 SubHeaderType; - * UINT32 SubHeaderLength; - * UINT32 SubHeaderUID; - * UINT64 DevicePathLength; - * UNIT8 DevicePath[DevicePathLength] + * UINT8 Signature[16]; + * UINT16 Version; + * UINT8 AuthState; + * UINT8 Reserved; + * UINT32 Length; + * UINT32 DeviceType; + * UINT32 SubHeaderType; + * UINT32 SubHeaderLength; + * UINT32 SubHeaderUID; + * UINT64 DevicePathLength; + * UNIT8 DevicePath[DevicePathLength] * } DEVICE_SECURITY_EVENT_DATA_HEADER2; *

* Fields common to both ..HEADER and ..HEADER2: - * Signature - * Version - * DeviceType - * DevicePathLength - * DevicePath + * Signature + * Version + * DeviceType + * DevicePathLength + * DevicePath *

*/ public abstract class DeviceSecurityEventHeader { + /** + * UEFI Device Path Length. + */ + @Getter + private static final int DEVICE_PATH_LENGTH = 0; /** * Contains the size (in bytes) of the header. */ @Getter private Integer dsedHeaderLength = 0; - /** * Signature (text) data. */ @@ -73,11 +77,6 @@ public abstract class DeviceSecurityEventHeader { */ @Getter private int deviceType = -1; - /** - * UEFI Device Path Length. - */ - @Getter - private int devicePathLength = 0; /** * UEFI Device path. */ @@ -129,21 +128,23 @@ public abstract class DeviceSecurityEventHeader { int startByteUpdated = startByte; // get the device path length - byte[] devicePathLengthBytes = new byte[8]; - System.arraycopy(dsedBytes, startByteUpdated, devicePathLengthBytes, 0, 8); - int devicePathLength = HexUtils.leReverseInt(devicePathLengthBytes); + final int devicePathLengthBytesSize = 8; + byte[] devicePathLengthBytes = new byte[devicePathLengthBytesSize]; + System.arraycopy(dsedBytes, startByteUpdated, devicePathLengthBytes, 0, devicePathLengthBytesSize); + int retrievedDevicePathLength = HexUtils.leReverseInt(devicePathLengthBytes); // get the device path - if (devicePathLength > 0) { - startByteUpdated = startByteUpdated + 8; - byte[] devPathBytes = new byte[devicePathLength]; + if (retrievedDevicePathLength > 0) { + final int startByteUpdatedOffset = 8; + startByteUpdated = startByteUpdated + startByteUpdatedOffset; + byte[] devPathBytes = new byte[retrievedDevicePathLength]; System.arraycopy(dsedBytes, startByteUpdated, devPathBytes, - 0, devicePathLength); + 0, retrievedDevicePathLength); devicePath = new UefiDevicePath(devPathBytes); } // header total size - dsedHeaderLength = startByteUpdated + devicePathLength; + dsedHeaderLength = startByteUpdated + retrievedDevicePathLength; } /** @@ -154,16 +155,12 @@ public abstract class DeviceSecurityEventHeader { * @return name of the device type */ public String deviceTypeToString(final int deviceTypeInt) { - switch (deviceTypeInt) { - case DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_NONE: - return "No device type"; - case DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_PCI: - return "PCI"; - case DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_USB: - return "USB"; - default: - return "Unknown or invalid Device Type"; - } + return switch (deviceTypeInt) { + case DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_NONE -> "No device type"; + case DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_PCI -> "PCI"; + case DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_USB -> "USB"; + default -> "Unknown or invalid Device Type"; + }; } /** diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvConstants.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvConstants.java index f71574db..8e9d05de 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvConstants.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvConstants.java @@ -6,11 +6,6 @@ package hirs.utils.tpm.eventlog.events; */ public final class EvConstants { - /** - * Default private constructor so checkstyles doesn't complain - */ - private EvConstants() { } - /** * Type length = 4 bytes. */ @@ -39,11 +34,11 @@ public final class EvConstants { * Each PCR bank holds 24 registers. */ public static final int PCR_COUNT = 24; - // Event IDs /** * Pre boot cert Event ID. */ public static final int EV_PREBOOT_CERT = 0x00000000; + // Event IDs /** * POST Code Event ID. */ @@ -180,4 +175,9 @@ public final class EvConstants { * EFI SPDM Device Authority Event ID. */ public static final int EV_EFI_SPDM_DEVICE_AUTHORITY = 0x800000E4; + /** + * Default private constructor so checkstyles doesn't complain. + */ + private EvConstants() { + } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvNoAction.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvNoAction.java index 5e38264d..983e2f44 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvNoAction.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/EvNoAction.java @@ -11,16 +11,16 @@ import java.nio.charset.StandardCharsets; * Class to process the EV_NO_ACTION event. * The first 16 bytes of the event data MUST be a String based identifier (Signature). * Currently defined Signatures are - * "Spec ID Event03" - * - implies the data is a TCG_EfiSpecIDEvent - * - TCG_EfiSpecIDEvent is the first event in a TPM Event Log and is used to determine - * if the format of the Log (SHA1 vs Crypto Agile). - * "StartupLocality" - * - implies the data represents locality info (use lookup to interpret) - * "NvIndexInstance" - * - implies the data is a NV_INDEX_INSTANCE_EVENT_LOG_DATA - * "NvIndexDynamic" - * - implies the data is a NV_INDEX_DYNAMIC_EVENT_LOG_DATA + * "Spec ID Event03" + * - implies the data is a TCG_EfiSpecIDEvent + * - TCG_EfiSpecIDEvent is the first event in a TPM Event Log and is used to determine + * if the format of the Log (SHA1 vs Crypto Agile). + * "StartupLocality" + * - implies the data represents locality info (use lookup to interpret) + * "NvIndexInstance" + * - implies the data is a NV_INDEX_INSTANCE_EVENT_LOG_DATA + * "NvIndexDynamic" + * - implies the data is a NV_INDEX_DYNAMIC_EVENT_LOG_DATA *

* Notes: * 1. First 16 bytes of the structure is an ASCII with a fixed Length of 16 @@ -66,7 +66,7 @@ public class EvNoAction { signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters if (signature.contains("Spec ID Event03")) { // implies CryptAgileFormat EvEfiSpecIdEvent specIDEvent = new EvEfiSpecIdEvent(eventData); - noActionInfo += specIDEventToString(specIDEvent).toString(); + noActionInfo += specIDEventToString(specIDEvent); bSpecIDEvent = true; specVersion = String.format("%s.%s", specIDEvent.getVersionMajor(), @@ -126,25 +126,21 @@ public class EvNoAction { * @return a description of the locality. */ private String getLocality(final byte[] eventData) { - String localityInfo = ""; + final int eventDataSrcIndex = 16; byte[] localityBytes = new byte[1]; - System.arraycopy(eventData, 16, localityBytes, 0, 1); - int locality = HexUtils.leReverseInt(localityBytes); + System.arraycopy(eventData, eventDataSrcIndex, localityBytes, 0, 1); + final int locality = HexUtils.leReverseInt(localityBytes); - switch (locality) { - case 0: - localityInfo += "Locality 0 without an H-CRTM sequence"; - break; - case 3: - localityInfo += "Locality 3 without an H-CRTM sequence"; - break; - case 4: - localityInfo += "Locality 4 with an H-CRTM sequence initialized"; - break; - default: - localityInfo += "Unknown"; - } - return localityInfo; + final int locality0 = 0; + final int locality3 = 3; + final int locality4 = 4; + + return switch (locality) { + case locality0 -> "Locality 0 without an H-CRTM sequence"; + case locality3 -> "Locality 3 without an H-CRTM sequence"; + case locality4 -> "Locality 4 with an H-CRTM sequence initialized"; + default -> "Unknown"; + }; } /** diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/NvIndexDynamicEventLogData.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/NvIndexDynamicEventLogData.java index f4318959..44e55233 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/NvIndexDynamicEventLogData.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/NvIndexDynamicEventLogData.java @@ -8,19 +8,19 @@ import java.nio.charset.StandardCharsets; * Class to process the NV_INDEX_DYNAMIC_EVENT_LOG_DATA per PFP. * Per PFP, the first 16 bytes of the structure are a String based identifier (Signature), * which are a NULL-terminated ASCII string "NvIndexDynamic". - * + *

* HEADERS defined by PFP v1.06 Rev 52. * Certain fields are common to both ..HEADER and ..HEADER2, and are noted below the structures. *

* typedef struct tdNV_INDEX_DYNAMIC_EVENT_LOG_DATA { - * BYTE Signature[16]; - * UINT16 Version; - * UINT8[6] Reserved; - * UINT64 UID; - * UINT16 DescriptionSize; - * UINT8 Description[DescriptionSize]; - * UINT16 DataSize; - * DEVICE_SECURITY_EVENT_DATA2 Data[DataSize]; + * BYTE Signature[16]; + * UINT16 Version; + * UINT8[6] Reserved; + * UINT64 UID; + * UINT16 DescriptionSize; + * UINT8 Description[DescriptionSize]; + * UINT16 DataSize; + * DEVICE_SECURITY_EVENT_DATA2 Data[DataSize]; * } NV_INDEX_DYNAMIC_EVENT_LOG_DATA; *

*/ @@ -43,13 +43,16 @@ public class NvIndexDynamicEventLogData { */ public NvIndexDynamicEventLogData(final byte[] eventData) { - byte[] signatureBytes = new byte[16]; - System.arraycopy(eventData, 0, signatureBytes, 0, 16); + final int signatureBytesSize = 16; + byte[] signatureBytes = new byte[signatureBytesSize]; + System.arraycopy(eventData, 0, signatureBytes, 0, signatureBytesSize); signature = new String(signatureBytes, StandardCharsets.UTF_8); signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters - byte[] versionBytes = new byte[2]; - System.arraycopy(eventData, 16, versionBytes, 0, 2); + final int versionBytesSize = 2; + final int eventDataSrcIndex1 = 16; + byte[] versionBytes = new byte[versionBytesSize]; + System.arraycopy(eventData, eventDataSrcIndex1, versionBytes, 0, versionBytesSize); String nvIndexVersion = HexUtils.byteArrayToHexString(versionBytes); if (nvIndexVersion.isEmpty()) { nvIndexVersion = "version not readable"; @@ -58,23 +61,28 @@ public class NvIndexDynamicEventLogData { nvIndexDynamicInfo += " Nv Index Dynamic Version = " + nvIndexVersion + "\n"; // 6 bytes of Reserved data - - byte[] uidBytes = new byte[8]; - System.arraycopy(eventData, 24, uidBytes, 0, 8); + final int uidBytesSize = 8; + final int eventDataSrcIndex2 = 24; + byte[] uidBytes = new byte[uidBytesSize]; + System.arraycopy(eventData, eventDataSrcIndex2, uidBytes, 0, uidBytesSize); String uid = HexUtils.byteArrayToHexString(uidBytes); nvIndexDynamicInfo += " UID = " + uid + "\n"; - byte[] descriptionSizeBytes = new byte[2]; - System.arraycopy(eventData, 32, descriptionSizeBytes, 0, 2); + final int descriptionSizeBytesLength = 2; + final int eventDataSrcIndex3 = 32; + byte[] descriptionSizeBytes = new byte[descriptionSizeBytesLength]; + System.arraycopy(eventData, eventDataSrcIndex3, descriptionSizeBytes, 0, descriptionSizeBytesLength); int descriptionSize = HexUtils.leReverseInt(descriptionSizeBytes); + final int eventDataSrcIndex4 = 34; byte[] descriptionBytes = new byte[descriptionSize]; - System.arraycopy(eventData, 34, descriptionBytes, 0, descriptionSize); + System.arraycopy(eventData, eventDataSrcIndex4, descriptionBytes, 0, descriptionSize); String description = new String(descriptionBytes, StandardCharsets.UTF_8); description = description.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters nvIndexDynamicInfo += " Description = " + description + "\n"; - int dataSizeStartByte = 34 + descriptionSize; + final int dataSizeOffset = 34; + int dataSizeStartByte = dataSizeOffset + descriptionSize; byte[] dataSizeBytes = new byte[2]; System.arraycopy(eventData, dataSizeStartByte, dataSizeBytes, 0, 2); int dataSize = HexUtils.leReverseInt(dataSizeBytes); diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/NvIndexInstanceEventLogData.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/NvIndexInstanceEventLogData.java index 1e6e9134..af573ead 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/NvIndexInstanceEventLogData.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/events/NvIndexInstanceEventLogData.java @@ -8,15 +8,15 @@ import java.nio.charset.StandardCharsets; * Class to process the NV_INDEX_INSTANCE_EVENT_LOG_DATA per PFP. * Per PFP, the first 16 bytes of the structure are a String based identifier (Signature), * which are a NULL-terminated ASCII string "NvIndexInstance". - * + *

* HEADERS defined by PFP v1.06 Rev 52. * Certain fields are common to both ..HEADER and ..HEADER2, and are noted below the structures. *

* typedef struct tdNV_INDEX_INSTANCE_EVENT_LOG_DATA { - * BYTE Signature[16]; - * UINT16 Version; - * UINT8[6] Reserved; - * DEVICE_SECURITY_EVENT_DATA2 Data; + * BYTE Signature[16]; + * UINT16 Version; + * UINT8[6] Reserved; + * DEVICE_SECURITY_EVENT_DATA2 Data; * } NV_INDEX_INSTANCE_EVENT_LOG_DATA; *

*/ @@ -45,13 +45,15 @@ public class NvIndexInstanceEventLogData { */ public NvIndexInstanceEventLogData(final byte[] eventData) { - byte[] signatureBytes = new byte[16]; - System.arraycopy(eventData, 0, signatureBytes, 0, 16); + final int signatureBytesSize = 16; + byte[] signatureBytes = new byte[signatureBytesSize]; + System.arraycopy(eventData, 0, signatureBytes, 0, signatureBytesSize); signature = new String(signatureBytes, StandardCharsets.UTF_8); signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters + final int eventDataSrcIndex1 = 16; byte[] versionBytes = new byte[2]; - System.arraycopy(eventData, 16, versionBytes, 0, 2); + System.arraycopy(eventData, eventDataSrcIndex1, versionBytes, 0, 2); String nvIndexVersion = HexUtils.byteArrayToHexString(versionBytes); if (nvIndexVersion == "") { nvIndexVersion = "version not readable"; @@ -60,14 +62,16 @@ public class NvIndexInstanceEventLogData { nvIndexInstanceInfo += " Nv Index Instance Version = " + nvIndexVersion + "\n"; // 6 bytes of Reserved data - - byte[] dsedSignatureBytes = new byte[16]; - System.arraycopy(eventData, 24, dsedSignatureBytes, 0, 16); + final int eventDataSrcIndex2 = 24; + final int dsedSignatureBytesSize = 16; + byte[] dsedSignatureBytes = new byte[dsedSignatureBytesSize]; + System.arraycopy(eventData, eventDataSrcIndex2, dsedSignatureBytes, 0, dsedSignatureBytesSize); String dsedSignature = new String(dsedSignatureBytes, StandardCharsets.UTF_8); dsedSignature = dsedSignature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters + final int eventDataSrcIndex3 = 40; byte[] dsedVersionBytes = new byte[2]; - System.arraycopy(eventData, 40, dsedVersionBytes, 0, 2); + System.arraycopy(eventData, eventDataSrcIndex3, dsedVersionBytes, 0, 2); String dsedVersion = HexUtils.byteArrayToHexString(dsedVersionBytes); if (dsedVersion == "") { dsedVersion = "version not readable"; @@ -75,9 +79,10 @@ public class NvIndexInstanceEventLogData { if (dsedSignature.contains("SPDM Device Sec2")) { - int dsedEventDataSize = eventData.length - 24; + final int eventDataSrcIndex4 = 24; + final int dsedEventDataSize = eventData.length - eventDataSrcIndex4; byte[] dsedEventData = new byte[dsedEventDataSize]; - System.arraycopy(eventData, 24, dsedEventData, 0, dsedEventDataSize); + System.arraycopy(eventData, eventDataSrcIndex4, dsedEventData, 0, dsedEventDataSize); nvIndexInstanceInfo += " Signature = SPDM Device Sec2\n"; @@ -89,7 +94,7 @@ public class NvIndexInstanceEventLogData { + dsedVersion + "\n"; } } else { - nvIndexInstanceInfo = " Signature error: should be \'SPDM Device Sec2\' but is " + nvIndexInstanceInfo = " Signature error: should be 'SPDM Device Sec2' but is " + signature + "\n"; } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmCertificateChain.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmCertificateChain.java index 8d0062c6..7ec8b8ea 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmCertificateChain.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmCertificateChain.java @@ -15,22 +15,22 @@ import java.util.ArrayList; *

* Certificate chain format, defined by SPDM v1.03, Sect 10.6.1, Table 33: * Certificate chain format { - * Length 2 bytes; - * Reserved 2 bytes; - * RootHash bytes; - * Certificates - (4 + ) bytes; + * Length 2 bytes; + * Reserved 2 bytes; + * RootHash bytes; + * Certificates - (4 + ) bytes; * } *

* Length: total length of cert chain including all fields in this block * H: the output size of the hash algorithm selected by the most recent ALGORITHMS response - * this field shall be in hash byte order - * hash algorithm is included in the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN - * structure as the member "SpdmBaseHashAlg" + * this field shall be in hash byte order + * hash algorithm is included in the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN + * structure as the member "SpdmBaseHashAlg" * RootHash: the digest of the Root Certificate. - * size is determined by hash algorithm selected by the most recent SPDM ALGORITHMS response; - * the hash algorithm is the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN SpdmBaseHashAlgo + * size is determined by hash algorithm selected by the most recent SPDM ALGORITHMS response; + * the hash algorithm is the DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN SpdmBaseHashAlgo * Certificates: Complete cert chain consisting of 1 or more ASN.1 DER-encoded X.509 v3 certs - * this field shall be in Encoded ASN.1 byte order + * this field shall be in Encoded ASN.1 byte order */ public class SpdmCertificateChain { @@ -38,6 +38,10 @@ public class SpdmCertificateChain { // * Length of the certificate chain to include all fields in this structure. // */ //private int length = 0; + /** + * Array List of certs found in the chain. + */ + private final ArrayList certList = new ArrayList(); /** * Root hash. */ @@ -46,10 +50,6 @@ public class SpdmCertificateChain { * Number of certs in the SPDM cert chain. */ private int numberOfCerts = 0; - /** - * Array List of certs found in the chain. - */ - private ArrayList certList = new ArrayList(); /** * Human-readable description of any error associated with SPDM base hash alg. */ @@ -63,7 +63,7 @@ public class SpdmCertificateChain { * SpdmCertificateChain Constructor. * * @param spdmCertChainBytes byte array holding the SPDM Cert Chain bytes. - * @param rootHashLength length of RootHash. + * @param rootHashLength length of RootHash. */ public SpdmCertificateChain(final byte[] spdmCertChainBytes, final int rootHashLength) { @@ -76,11 +76,13 @@ public class SpdmCertificateChain { // Reserved: 2 bytes + final int spdmCertChainBytesSrcIndex = 4; rootHash = new byte[rootHashLength]; - System.arraycopy(spdmCertChainBytes, 4, rootHash, 0, rootHashLength); + System.arraycopy(spdmCertChainBytes, spdmCertChainBytesSrcIndex, rootHash, 0, rootHashLength); - int certChainStartPos = 4 + rootHashLength; - int certChainLength = spdmCertChainBytes.length - certChainStartPos; + final int offsetForCertChain = 4; + final int certChainStartPos = offsetForCertChain + rootHashLength; + final int certChainLength = spdmCertChainBytes.length - certChainStartPos; byte[] certChainBytes = new byte[certChainLength]; System.arraycopy(spdmCertChainBytes, certChainStartPos, certChainBytes, 0, certChainLength); @@ -93,7 +95,7 @@ public class SpdmCertificateChain { * * @param certChainData Byte array holding the cert chain data */ - private void processCertChain(final byte[] certChainData) { + private void processCertChain(final byte[] certChainData) { UefiX509Cert cert = null; @@ -113,10 +115,11 @@ public class SpdmCertificateChain { byte[] certData = new byte[cLength]; certChainDataIS.read(certData); // put the cert back together - byte[] certBlob = new byte[cLength + 4]; + final int certBlobStartIndex = 4; + byte[] certBlob = new byte[cLength + certBlobStartIndex]; System.arraycopy(certType, 0, certBlob, 0, 2); System.arraycopy(certLength, 0, certBlob, 2, 2); - System.arraycopy(certData, 0, certBlob, 4, cLength); + System.arraycopy(certData, 0, certBlob, certBlobStartIndex, cLength); cert = new UefiX509Cert(certBlob); //cert = new X509Certificate(certBlob); certList.add(cert); diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java index b64d013b..91414da7 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmHa.java @@ -4,12 +4,7 @@ package hirs.utils.tpm.eventlog.spdm; * Class for defining hash algorithms referenced in the DMTF SPDM specification. * SPDM 1.3.0, Table 21, MeasurementHashAlgo. */ -public class SpdmHa { - - /** - * Default private constructor so checkstyles doesn't complain - */ - private SpdmHa() { } +public final class SpdmHa { /** * Spdm Hash Alg = Raw bit stream. @@ -40,6 +35,12 @@ public class SpdmHa { */ public static final int TPM_ALG_SHA3_512 = 64; + /** + * Default private constructor so checkstyles doesn't complain. + */ + private SpdmHa() { + } + /** * Returns the hash name via a lookup. * Lookup based upon SPDM Spec v1.03 section 10.4. @@ -48,32 +49,16 @@ public class SpdmHa { * @return name of the algorithm */ public static String tcgAlgIdToString(final int algId) { - String alg; - switch (algId) { - case TPM_ALG_RAW: - alg = "Raw Bit Stream"; - break; - case TPM_ALG_SHA_256: - alg = "TPM_ALG_SHA_256"; - break; - case TPM_ALG_SHA_384: - alg = "TPM_ALG_SHA_384"; - break; - case TPM_ALG_SHA_512: - alg = "TPM_ALG_SHA_512"; - break; - case TPM_ALG_SHA3_256: - alg = "TPM_ALG_SHA3_256"; - break; - case TPM_ALG_SHA3_384: - alg = "TPM_ALG_SHA3_384"; - break; - case TPM_ALG_SHA3_512: - alg = "TPM_ALG_SHA3_512"; - break; - default: - alg = "Unknown or invalid Hash"; - } + String alg = switch (algId) { + case TPM_ALG_RAW -> "Raw Bit Stream"; + case TPM_ALG_SHA_256 -> "TPM_ALG_SHA_256"; + case TPM_ALG_SHA_384 -> "TPM_ALG_SHA_384"; + case TPM_ALG_SHA_512 -> "TPM_ALG_SHA_512"; + case TPM_ALG_SHA3_256 -> "TPM_ALG_SHA3_256"; + case TPM_ALG_SHA3_384 -> "TPM_ALG_SHA3_384"; + case TPM_ALG_SHA3_512 -> "TPM_ALG_SHA3_512"; + default -> "Unknown or invalid Hash"; + }; return alg; } @@ -85,32 +70,17 @@ public class SpdmHa { * @return size of the algorithm output */ public static int tcgAlgIdToByteSize(final int algId) { - int byteSize; - switch (algId) { - //case TPM_ALG_RAW: // add this when have more test data - // byteSize = ; - // break; - case TPM_ALG_SHA_256: - byteSize = 32; - break; - case TPM_ALG_SHA_384: - byteSize = 48; - break; - case TPM_ALG_SHA_512: - byteSize = 64; - break; - case TPM_ALG_SHA3_256: - byteSize = 32; - break; - case TPM_ALG_SHA3_384: - byteSize = 48; - break; - case TPM_ALG_SHA3_512: - byteSize = 64; - break; - default: - byteSize = -1; - } - return byteSize; + final int byteSize256 = 32; + final int byteSize384 = 48; + final int byteSize512 = 64; + + return switch (algId) { +// case TPM_ALG_RAW: // add this when have more test data +// return ; + case TPM_ALG_SHA_256, TPM_ALG_SHA3_256 -> byteSize256; + case TPM_ALG_SHA_384, TPM_ALG_SHA3_384 -> byteSize384; + case TPM_ALG_SHA_512, TPM_ALG_SHA3_512 -> byteSize512; + default -> -1; + }; } } diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurement.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurement.java index 4a90cacb..9ef63e94 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurement.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/SpdmMeasurement.java @@ -8,34 +8,89 @@ import lombok.Getter; *

* Measurement, defined by SPDM v1.03, Sect 10.11.1, Table 54: * DMTF measurement spec format { - * DMTFSpecMeasurementValueType 1 byte; - * DMTFSpecMeasurementValueSize 2 bytes; - * DMTFSpecMeasurementValue bytes; + * DMTFSpecMeasurementValueType 1 byte; + * DMTFSpecMeasurementValueSize 2 bytes; + * DMTFSpecMeasurementValue bytes; * } *

* DMTFSpecMeasurementValueType[7] - * Indicates how bits [0:6] are represented - * Bit = 0: Digest - * Bit = 1: Raw bit stream + * Indicates how bits [0:6] are represented + * Bit = 0: Digest + * Bit = 1: Raw bit stream * DMTFSpecMeasurementValueType[6:0] (see SPDM Spec, Table 55 "DMTFSpecMeasurementValueType[6:0]") - * Immutable ROM 0x0 - * Mutable firmware 0x1 - * Hardware configuration 0x2 - * Firmware configuration 0x3 - * etc. + * Immutable ROM 0x0 + * Mutable firmware 0x1 + * Hardware configuration 0x2 + * Firmware configuration 0x3 + * etc. *

*/ public class SpdmMeasurement { + /** + * MEASUREMENT_VALUE_0 = Immutable ROM. + */ + private static final int MEASUREMENT_VALUE_0 = 0; + + /** + * MEASUREMENT_VALUE_1 = Mutable firmware. + */ + private static final int MEASUREMENT_VALUE_1 = 1; + + /** + * MEASUREMENT_VALUE_2 = Hardware configuration. + */ + private static final int MEASUREMENT_VALUE_2 = 2; + + /** + * MEASUREMENT_VALUE_3 = Firmware configuration. + */ + private static final int MEASUREMENT_VALUE_3 = 3; + + /** + * MEASUREMENT_VALUE_4 = Freeform measurement manifest. + */ + private static final int MEASUREMENT_VALUE_4 = 4; + + /** + * MEASUREMENT_VALUE_5 = Structured representation of debug and device mode. + */ + private static final int MEASUREMENT_VALUE_5 = 5; + + /** + * MEASUREMENT_VALUE_6 = Mutable firmware's version number. + */ + private static final int MEASUREMENT_VALUE_6 = 6; + + /** + * MEASUREMENT_VALUE_7 = Mutable firmware's security version number. + */ + private static final int MEASUREMENT_VALUE_7 = 7; + + /** + * MEASUREMENT_VALUE_8 = Hash-extended measurement. + */ + private static final int MEASUREMENT_VALUE_8 = 8; + + /** + * MEASUREMENT_VALUE_9 = Informational. + */ + private static final int MEASUREMENT_VALUE_9 = 9; + + /** + * MEASUREMENT_VALUE_10 = Structured measurement manifest. + */ + private static final int MEASUREMENT_VALUE_10 = 10; + + /** + * Measurement value (digest). + */ + private final byte[] dmtfSpecMeasurementValue; /** * Measurement value type (such as mutable firmware, etc). */ @Getter private int dmtfSpecMeasurementValueType = 0; - /** - * Measurement value (digest). - */ - private byte[] dmtfSpecMeasurementValue; /** * SpdmMeasurement Constructor. @@ -49,14 +104,16 @@ public class SpdmMeasurement { 1); dmtfSpecMeasurementValueType = HexUtils.leReverseInt(dmtfSpecMeasurementValueTypeBytes); - // in future, can crosscheck this value size + 3 with the spdm block MeasurementSize size + // in the future, can crosscheck this value size + 3 with the spdm block MeasurementSize size byte[] dmtfSpecMeasurementValueSizeBytes = new byte[2]; System.arraycopy(spdmMeasBytes, 1, dmtfSpecMeasurementValueSizeBytes, 0, 2); int dmtfSpecMeasurementValueSize = HexUtils.leReverseInt(dmtfSpecMeasurementValueSizeBytes); dmtfSpecMeasurementValue = new byte[dmtfSpecMeasurementValueSize]; - System.arraycopy(spdmMeasBytes, 3, dmtfSpecMeasurementValue, 0, + + final int sourceIndex = 3; + System.arraycopy(spdmMeasBytes, sourceIndex, dmtfSpecMeasurementValue, 0, dmtfSpecMeasurementValueSize); } @@ -64,50 +121,23 @@ public class SpdmMeasurement { * Lookup for SPDM measurement value type. * * @param measValType the numerical representation of the measurement value type. - * * @return a description of the measurement value type. */ public String dmtfSpecMeasurementValueTypeToString(final int measValType) { - - String measValTypeStr; - switch (measValType) { - case 0: - measValTypeStr = "Immutable ROM"; - break; - case 1: - measValTypeStr = "Mutable firmware"; - break; - case 2: - measValTypeStr = "Hardware configuration"; - break; - case 3: - measValTypeStr = "Firmware configuration"; - break; - case 4: - measValTypeStr = "Freeform measurement manifest"; - break; - case 5: - measValTypeStr = "Structured representation of debug and device mode"; - break; - case 6: - measValTypeStr = "Mutable firmware's version number"; - break; - case 7: - measValTypeStr = "Mutable firmware's security version number"; - break; - case 8: - measValTypeStr = "Hash-extended measurement"; - break; - case 9: - measValTypeStr = "Informational"; - break; - case 10: - measValTypeStr = "Structured measurement manifest"; - break; - default: - measValTypeStr = "Unknown or invalid DMTF Spec Measurement Value Type"; - } - return measValTypeStr; + return switch (measValType) { + case MEASUREMENT_VALUE_0 -> "Immutable ROM"; + case MEASUREMENT_VALUE_1 -> "Mutable firmware"; + case MEASUREMENT_VALUE_2 -> "Hardware configuration"; + case MEASUREMENT_VALUE_3 -> "Firmware configuration"; + case MEASUREMENT_VALUE_4 -> "Freeform measurement manifest"; + case MEASUREMENT_VALUE_5 -> "Structured representation of debug and device mode"; + case MEASUREMENT_VALUE_6 -> "Mutable firmware's version number"; + case MEASUREMENT_VALUE_7 -> "Mutable firmware's security version number"; + case MEASUREMENT_VALUE_8 -> "Hash-extended measurement"; + case MEASUREMENT_VALUE_9 -> "Informational"; + case MEASUREMENT_VALUE_10 -> "Structured measurement manifest"; + default -> "Unknown or invalid DMTF Spec Measurement Value Type"; + }; } /** diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/package-info.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/package-info.java index 64b778b4..f76263ad 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/package-info.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/spdm/package-info.java @@ -2,4 +2,4 @@ * Non-persistent classes related to TGC Event Logs. */ -package hirs.utils.tpm.eventlog.spdm; \ No newline at end of file +package hirs.utils.tpm.eventlog.spdm; diff --git a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiConstants.java b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiConstants.java index 655ffa68..71e94243 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiConstants.java +++ b/HIRS_Utils/src/main/java/hirs/utils/tpm/eventlog/uefi/UefiConstants.java @@ -7,11 +7,6 @@ package hirs.utils.tpm.eventlog.uefi; */ public final class UefiConstants { - /** - * Default private constructor so checkstyles doesn't complain - */ - private UefiConstants() { } - /** * 2 byte size. */ @@ -278,13 +273,18 @@ public final class UefiConstants { public static final String FILESTATUS_FROM_FILESYSTEM = "fileFromFilesystem"; /** * file status, where file was not found on local machine, so file from code was used. - * For instance, if vendor-table.json is not found in filesystem at location - * /etc/hirs/aca/default-properties/, it will be grabbed from code at - * HIRS_AttestationCA/src/main/resources/. + * For instance, if vendor-table.json is not found in filesystem at location + * /etc/hirs/aca/default-properties/, it will be grabbed from code at + * HIRS_AttestationCA/src/main/resources/. */ public static final String FILESTATUS_FROM_CODE = "fileFromCode"; /** * file status, where file is not accessible (either not found, or no access permission). */ public static final String FILESTATUS_NOT_ACCESSIBLE = "fileNotAccessible"; + /** + * Default private constructor so checkstyles doesn't complain. + */ + private UefiConstants() { + } } diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java index c0f4a82a..bc030f81 100644 --- a/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java +++ b/HIRS_Utils/src/test/java/hirs/data/persist/DigestTest.java @@ -1,436 +1,20 @@ package hirs.data.persist; -import java.util.Arrays; - import hirs.utils.digest.Digest; import hirs.utils.digest.DigestAlgorithm; import hirs.utils.digest.DigestComparisonResultType; import org.apache.commons.codec.digest.DigestUtils; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.Arrays; + /** * Unit tests for the Digest class. */ public class DigestTest { private static final int DIGEST_LENGTH_BYTES = 20; - /** - * Tests that constructor throws a IllegalArgumentException when a - * null DigestAlgorithm is passed into constructor. - */ - @Test - public final void nullAlgorithm() { - final byte[] digest = getTestDigest(16); - Assertions.assertThrows(IllegalArgumentException.class, - () -> new Digest(null, digest)); - } - - /** - * Tests that constructor throws a IllegalArgumentException when a - * null digest is passed into constructor. - */ - @Test - public final void nullDigest() { - Assertions.assertThrows(IllegalArgumentException.class, - () -> new Digest(DigestAlgorithm.MD2, null)); - } - - /** - * Tests that constructor throws a IllegalArgumentException when an - * digest that is an empty array is passed into constructor. - */ - @Test - public final void emptyArrayDigest() { - Assertions.assertThrows(IllegalArgumentException.class, - () -> new Digest(DigestAlgorithm.MD2, new byte[0])); - } - - /** - * Tests that MD2 digest can be created. - */ - @Test - public final void md2() { - final byte[] digest = getTestDigest(16); - final Digest d = new Digest(DigestAlgorithm.MD2, digest); - Assertions.assertNotNull(d); - } - - /** - * Tests that an MD2 digest can be recreated from a string. - */ - @Test - public final void testFromStringMD2() { - final byte[] digestBytes = getTestDigest(16); - Digest digest = new Digest(DigestAlgorithm.MD2, digestBytes); - String digestString = digest.toString(); - Digest digestFromString = Digest.fromString(digestString); - Assertions.assertEquals(digest, digestFromString); - } - - /** - * Tests that MD2 digest cannot be created with a digest that has extra - * bytes. - */ - @Test - public final void md2IllegalDigest() { - final byte[] digest = getTestDigest(17); - Assertions.assertThrows(IllegalArgumentException.class, - () -> new Digest(DigestAlgorithm.MD2, digest)); - } - - /** - * Tests that MD5 digest can be created. - */ - @Test - public final void md5() { - final byte[] digest = getTestDigest(16); - final Digest d = new Digest(DigestAlgorithm.MD5, digest); - Assertions.assertNotNull(d); - } - - /** - * Tests that an MD5 digest can be recreated from a string. - */ - @Test - public final void testFromStringMD5() { - final byte[] digestBytes = getTestDigest(16); - Digest digest = new Digest(DigestAlgorithm.MD5, digestBytes); - String digestString = digest.toString(); - Digest digestFromString = Digest.fromString(digestString); - Assertions.assertEquals(digest, digestFromString); - } - - /** - * Tests that MD5 digest cannot be created with a digest that has extra - * bytes. - */ - @Test - public final void md5IllegalDigest() { - final byte[] digest = getTestDigest(17); - Assertions.assertThrows(IllegalArgumentException.class, - () -> new Digest(DigestAlgorithm.MD5, digest)); - } - - /** - * Tests that SHA1 digest can be created. - */ - @Test - public final void sha1() { - final byte[] digest = getTestDigest(20); - final Digest d = new Digest(DigestAlgorithm.SHA1, digest); - Assertions.assertNotNull(d); - } - - /** - * Tests that SHA1 digest can be recreated from a string. - */ - @Test - public final void testFromStringSHA1() { - final byte[] digestBytes = getTestDigest(20); - Digest digest = new Digest(DigestAlgorithm.SHA1, digestBytes); - String digestString = digest.toString(); - Digest digestFromString = Digest.fromString(digestString); - Assertions.assertEquals(digest, digestFromString); - } - - /** - * Tests that SHA1 digest cannot be created with a digest that has extra - * bytes. - */ - @Test - public final void sha1IllegalDigest() { - final byte[] digest = getTestDigest(21); - Assertions.assertThrows(IllegalArgumentException.class, - () -> new Digest(DigestAlgorithm.SHA1, digest)); - } - - /** - * Tests that SHA256 digest can be created. - */ - @Test - public final void sha256() { - final byte[] digest = getTestDigest(32); - final Digest d = new Digest(DigestAlgorithm.SHA256, digest); - Assertions.assertNotNull(d); - } - - /** - * Tests that SHA256 digest can be recreated from a string. - */ - @Test - public final void testFromStringSHA256() { - final byte[] digestBytes = getTestDigest(32); - Digest digest = new Digest(DigestAlgorithm.SHA256, digestBytes); - String digestString = digest.toString(); - Digest digestFromString = Digest.fromString(digestString); - Assertions.assertEquals(digest, digestFromString); - } - - /** - * Tests that SHA256 digest cannot be created with a digest that has extra - * bytes. - */ - @Test - public final void sha256IllegalDigest() { - final byte[] digest = getTestDigest(33); - Assertions.assertThrows(IllegalArgumentException.class, - () -> new Digest(DigestAlgorithm.SHA256, digest)); - } - - /** - * Tests that SHA384 digest can be created. - */ - @Test - public final void sha384() { - final byte[] digest = getTestDigest(48); - final Digest d = new Digest(DigestAlgorithm.SHA384, digest); - Assertions.assertNotNull(d); - } - - /** - * Tests that SHA384 digest can be recreated from a string. - */ - @Test - public final void testFromStringSHA384() { - final byte[] digestBytes = getTestDigest(48); - Digest digest = new Digest(DigestAlgorithm.SHA384, digestBytes); - String digestString = digest.toString(); - Digest digestFromString = Digest.fromString(digestString); - Assertions.assertEquals(digest, digestFromString); - } - - /** - * Tests that SHA384 digest cannot be created with a digest that has extra - * bytes. - */ - @Test - public final void sha384IllegalDigest() { - final byte[] digest = getTestDigest(49); - Assertions.assertThrows(IllegalArgumentException.class, - () -> new Digest(DigestAlgorithm.SHA384, digest)); - } - - /** - * Tests that SHA512 digest can be created. - */ - @Test - public final void sha512() { - final byte[] digest = getTestDigest(64); - final Digest d = new Digest(DigestAlgorithm.SHA512, digest); - Assertions.assertNotNull(d); - } - - /** - * Tests that SHA512 digest can be recreated from a string. - */ - @Test - public final void testFromStringSHA512() { - final byte[] digestBytes = getTestDigest(64); - Digest digest = new Digest(DigestAlgorithm.SHA512, digestBytes); - String digestString = digest.toString(); - Digest digestFromString = Digest.fromString(digestString); - Assertions.assertEquals(digest, digestFromString); - } - - /** - * Tests that SHA512 digest cannot be created with a digest that has extra - * bytes. - */ - @Test - public final void sha512IllegalDigest() { - final byte[] digest = getTestDigest(65); - Assertions.assertThrows(IllegalArgumentException.class, - () -> new Digest(DigestAlgorithm.SHA512, digest)); - } - - /** - * Tests that the correct DigestAlgorithm is returned by - * {@link Digest#getAlgorithm()}. - */ - @Test - public final void testGetAlgorithm() { - final Digest d = new Digest(DigestAlgorithm.SHA1, getTestDigest(20)); - Assertions.assertEquals(d.getAlgorithm(), DigestAlgorithm.SHA1); - } - - /** - * Tests that the bytes of the digest are created and do not affect the - * underlying state of the Digest instance. - */ - @Test - public final void testGetDigest() { - final Digest d = new Digest(DigestAlgorithm.SHA1, getTestDigest(20)); - final byte[] digestBytes = d.getDigest(); - final byte[] testBytes = getTestDigest(20); - Assertions.assertArrayEquals(digestBytes, testBytes); - digestBytes[0] = (byte) (digestBytes[0] + 1); - Assertions.assertArrayEquals(d.getDigest(), testBytes); - Assertions.assertFalse(Arrays.equals(d.getDigest(), digestBytes)); - } - - /** - * Tests that two Digests have equal hash code for same - * algorithm and digest. - */ - @Test - public final void testHashCodeEqual() { - final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20)); - final Digest d2 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20)); - Assertions.assertEquals(d2.hashCode(), d1.hashCode()); - } - - /** - * Tests that two Digests indicate MATCH when compared. - */ - @Test - public final void testMatchedComparison() { - final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20)); - final Digest d2 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20)); - Assertions.assertEquals(DigestComparisonResultType.MATCH, d1.compare(d2)); - Assertions.assertEquals(DigestComparisonResultType.MATCH, d2.compare(d1)); - } - - /** - * Tests that two Digests have unequal hash code for same - * digest but different algorithm. - */ - @Test - public final void testHashCodeNotEqualAlgorithm() { - final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(16)); - final Digest d2 = new Digest(DigestAlgorithm.MD5, getTestDigest(16)); - Assertions.assertNotEquals(d2.hashCode(), d1.hashCode()); - } - - /** - * Tests that two Digests indicate MISMATCH when compared. - */ - @Test - public final void testMismatchAlgorithm() { - final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(16)); - final Digest d2 = new Digest(DigestAlgorithm.MD5, getTestDigest(16)); - Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2)); - Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d2.compare(d1)); - } - - /** - * Tests that two Digests have unequal hash code for same - * algorithm but different digest. - */ - @Test - public final void testHashCodeNotEqualDigest() { - final byte[] digest = getTestDigest(20); - final Digest d1 = new Digest(DigestAlgorithm.SHA1, digest); - digest[0] += 1; - final Digest d2 = new Digest(DigestAlgorithm.SHA1, digest); - Assertions.assertNotEquals(d2.hashCode(), d1.hashCode()); - Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2)); - } - - /** - * Tests that two Digests are equal for same algorithm and - * digest. - */ - @Test - public final void testEqual() { - final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20)); - final Digest d2 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20)); - Assertions.assertEquals(d2, d1); - } - - /** - * Tests that two Digests are unequal for same digest but - * different algorithm. - */ - @Test - public final void testNotEqualAlgorithm() { - final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(16)); - final Digest d2 = new Digest(DigestAlgorithm.MD5, getTestDigest(16)); - Assertions.assertNotEquals(d2, d1); - } - - /** - * Tests that two Digests are unequal for same algorithm but - * different digest. - */ - @Test - public final void testNotEqualDigest() { - final byte[] digest = getTestDigest(20); - final Digest d1 = new Digest(DigestAlgorithm.SHA1, digest); - digest[0] += 1; - final Digest d2 = new Digest(DigestAlgorithm.SHA1, digest); - Assertions.assertNotEquals(d2, d1); - } - - /** - * Tests that comparing a null Digest to a Digest indicates an UNKNOWN - * comparison type. - */ - @Test - public final void testCompareToNull() { - final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(16)); - Assertions.assertEquals(DigestComparisonResultType.UNKNOWN, d1.compare(null)); - } - - /** - * Tests that comparing two Digests with hashes with values of zero gives a MATCH - * comparison result. - */ - @Test - public final void testCompareToDigestWithBothZeroizedHash() { - final Digest d1 = new Digest(DigestAlgorithm.SHA1, getZeroValueDigest(20)); - final Digest d2 = new Digest(DigestAlgorithm.SHA1, getZeroValueDigest(20)); - Assertions.assertEquals(DigestComparisonResultType.MATCH, d1.compare(d2)); - Assertions.assertEquals(DigestComparisonResultType.MATCH, d2.compare(d1)); - } - - /** - * Tests that comparing two Digests, one with a hash of value zero, gives a MISMATCH - * comparison result. - */ - @Test - public final void testCompareToDigestWithOneZeroizedHash() { - final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20)); - final Digest d2 = new Digest(DigestAlgorithm.SHA1, getZeroValueDigest(20)); - Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2)); - Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d2.compare(d1)); - } - - /** - * Tests that comparing two Digests with a hash of no data gives a MATCH - * comparison result. - */ - @Test - public final void testCompareToDigestWithBothEmptyHash() { - final Digest d1 = new Digest(DigestAlgorithm.SHA1, getEmptySHA1Digest()); - final Digest d2 = new Digest(DigestAlgorithm.SHA1, getEmptySHA1Digest()); - Assertions.assertEquals(DigestComparisonResultType.MATCH, d1.compare(d2)); - Assertions.assertEquals(DigestComparisonResultType.MATCH, d2.compare(d1)); - } - - /** - * Tests that comparing two Digests, one with a hash of no data, gives a MISMATCH - * comparison result. - */ - @Test - public final void testCompareToDigestWithOneEmptyHash() { - final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(20)); - final Digest d2 = new Digest(DigestAlgorithm.SHA1, getEmptySHA1Digest()); - Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2)); - Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d2.compare(d1)); - } - - /** - * Tests that if someone tries to recreate a Digest using an invalid String, an error is thrown. - */ - @Test - public final void testFromStringInvalid() { - String invalidDigestString = "SHA1 00000000000000000000"; - Assertions.assertThrows(IllegalArgumentException.class, - () -> Digest.fromString(invalidDigestString)); - } - /** * Get a test SHA1 digest. * @@ -464,7 +48,455 @@ public class DigestTest { return new byte[count]; } + /** + * Tests that constructor throws a IllegalArgumentException when a + * null DigestAlgorithm is passed into constructor. + */ + @Test + public final void nullAlgorithm() { + final int count = 16; + final byte[] digest = getTestDigest(count); + Assertions.assertThrows(IllegalArgumentException.class, + () -> new Digest(null, digest)); + } + + /** + * Tests that constructor throws a IllegalArgumentException when a + * null digest is passed into constructor. + */ + @Test + public final void nullDigest() { + Assertions.assertThrows(IllegalArgumentException.class, + () -> new Digest(DigestAlgorithm.MD2, null)); + } + + /** + * Tests that constructor throws a IllegalArgumentException when an + * digest that is an empty array is passed into constructor. + */ + @Test + public final void emptyArrayDigest() { + Assertions.assertThrows(IllegalArgumentException.class, + () -> new Digest(DigestAlgorithm.MD2, new byte[0])); + } + + /** + * Tests that MD2 digest can be created. + */ + @Test + public final void md2() { + final int count = 16; + final byte[] digest = getTestDigest(count); + final Digest d = new Digest(DigestAlgorithm.MD2, digest); + Assertions.assertNotNull(d); + } + + /** + * Tests that an MD2 digest can be recreated from a string. + */ + @Test + public final void testFromStringMD2() { + final int count = 16; + final byte[] digestBytes = getTestDigest(count); + Digest digest = new Digest(DigestAlgorithm.MD2, digestBytes); + String digestString = digest.toString(); + Digest digestFromString = Digest.fromString(digestString); + Assertions.assertEquals(digest, digestFromString); + } + + /** + * Tests that MD2 digest cannot be created with a digest that has extra + * bytes. + */ + @Test + public final void md2IllegalDigest() { + final int count = 17; + final byte[] digest = getTestDigest(count); + Assertions.assertThrows(IllegalArgumentException.class, + () -> new Digest(DigestAlgorithm.MD2, digest)); + } + + /** + * Tests that MD5 digest can be created. + */ + @Test + public final void md5() { + final int count = 16; + final byte[] digest = getTestDigest(count); + final Digest d = new Digest(DigestAlgorithm.MD5, digest); + Assertions.assertNotNull(d); + } + + /** + * Tests that an MD5 digest can be recreated from a string. + */ + @Test + public final void testFromStringMD5() { + final int count = 16; + final byte[] digestBytes = getTestDigest(count); + Digest digest = new Digest(DigestAlgorithm.MD5, digestBytes); + String digestString = digest.toString(); + Digest digestFromString = Digest.fromString(digestString); + Assertions.assertEquals(digest, digestFromString); + } + + /** + * Tests that MD5 digest cannot be created with a digest that has extra + * bytes. + */ + @Test + public final void md5IllegalDigest() { + final int count = 17; + final byte[] digest = getTestDigest(count); + Assertions.assertThrows(IllegalArgumentException.class, + () -> new Digest(DigestAlgorithm.MD5, digest)); + } + + /** + * Tests that SHA1 digest can be created. + */ + @Test + public final void sha1() { + final int count = 20; + final byte[] digest = getTestDigest(count); + final Digest d = new Digest(DigestAlgorithm.SHA1, digest); + Assertions.assertNotNull(d); + } + + /** + * Tests that SHA1 digest can be recreated from a string. + */ + @Test + public final void testFromStringSHA1() { + final int count = 20; + final byte[] digestBytes = getTestDigest(count); + Digest digest = new Digest(DigestAlgorithm.SHA1, digestBytes); + String digestString = digest.toString(); + Digest digestFromString = Digest.fromString(digestString); + Assertions.assertEquals(digest, digestFromString); + } + + /** + * Tests that SHA1 digest cannot be created with a digest that has extra + * bytes. + */ + @Test + public final void sha1IllegalDigest() { + final int count = 21; + final byte[] digest = getTestDigest(count); + Assertions.assertThrows(IllegalArgumentException.class, + () -> new Digest(DigestAlgorithm.SHA1, digest)); + } + + /** + * Tests that SHA256 digest can be created. + */ + @Test + public final void sha256() { + final int count = 32; + final byte[] digest = getTestDigest(count); + final Digest d = new Digest(DigestAlgorithm.SHA256, digest); + Assertions.assertNotNull(d); + } + + /** + * Tests that SHA256 digest can be recreated from a string. + */ + @Test + public final void testFromStringSHA256() { + final int count = 32; + final byte[] digestBytes = getTestDigest(count); + Digest digest = new Digest(DigestAlgorithm.SHA256, digestBytes); + String digestString = digest.toString(); + Digest digestFromString = Digest.fromString(digestString); + Assertions.assertEquals(digest, digestFromString); + } + + /** + * Tests that SHA256 digest cannot be created with a digest that has extra + * bytes. + */ + @Test + public final void sha256IllegalDigest() { + final int count = 33; + final byte[] digest = getTestDigest(count); + Assertions.assertThrows(IllegalArgumentException.class, + () -> new Digest(DigestAlgorithm.SHA256, digest)); + } + + /** + * Tests that SHA384 digest can be created. + */ + @Test + public final void sha384() { + final int count = 48; + final byte[] digest = getTestDigest(count); + final Digest d = new Digest(DigestAlgorithm.SHA384, digest); + Assertions.assertNotNull(d); + } + + /** + * Tests that SHA384 digest can be recreated from a string. + */ + @Test + public final void testFromStringSHA384() { + final int count = 48; + final byte[] digestBytes = getTestDigest(count); + Digest digest = new Digest(DigestAlgorithm.SHA384, digestBytes); + String digestString = digest.toString(); + Digest digestFromString = Digest.fromString(digestString); + Assertions.assertEquals(digest, digestFromString); + } + + /** + * Tests that SHA384 digest cannot be created with a digest that has extra + * bytes. + */ + @Test + public final void sha384IllegalDigest() { + final int count = 49; + final byte[] digest = getTestDigest(count); + Assertions.assertThrows(IllegalArgumentException.class, + () -> new Digest(DigestAlgorithm.SHA384, digest)); + } + + /** + * Tests that SHA512 digest can be created. + */ + @Test + public final void sha512() { + final int count = 64; + final byte[] digest = getTestDigest(count); + final Digest d = new Digest(DigestAlgorithm.SHA512, digest); + Assertions.assertNotNull(d); + } + + /** + * Tests that SHA512 digest can be recreated from a string. + */ + @Test + public final void testFromStringSHA512() { + final int count = 64; + final byte[] digestBytes = getTestDigest(count); + Digest digest = new Digest(DigestAlgorithm.SHA512, digestBytes); + String digestString = digest.toString(); + Digest digestFromString = Digest.fromString(digestString); + Assertions.assertEquals(digest, digestFromString); + } + + /** + * Tests that SHA512 digest cannot be created with a digest that has extra + * bytes. + */ + @Test + public final void sha512IllegalDigest() { + final int count = 65; + final byte[] digest = getTestDigest(count); + Assertions.assertThrows(IllegalArgumentException.class, + () -> new Digest(DigestAlgorithm.SHA512, digest)); + } + + /** + * Tests that the correct DigestAlgorithm is returned by + * {@link Digest#getAlgorithm()}. + */ + @Test + public final void testGetAlgorithm() { + final int count = 20; + final Digest d = new Digest(DigestAlgorithm.SHA1, getTestDigest(count)); + Assertions.assertEquals(d.getAlgorithm(), DigestAlgorithm.SHA1); + } + + /** + * Tests that the bytes of the digest are created and do not affect the + * underlying state of the Digest instance. + */ + @Test + public final void testGetDigest() { + final int count = 20; + final Digest d = new Digest(DigestAlgorithm.SHA1, getTestDigest(count)); + final byte[] digestBytes = d.getDigest(); + final byte[] testBytes = getTestDigest(count); + Assertions.assertArrayEquals(digestBytes, testBytes); + digestBytes[0] = (byte) (digestBytes[0] + 1); + Assertions.assertArrayEquals(d.getDigest(), testBytes); + Assertions.assertFalse(Arrays.equals(d.getDigest(), digestBytes)); + } + + /** + * Tests that two Digests have equal hash code for same + * algorithm and digest. + */ + @Test + public final void testHashCodeEqual() { + final int count = 20; + final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(count)); + final Digest d2 = new Digest(DigestAlgorithm.SHA1, getTestDigest(count)); + Assertions.assertEquals(d2.hashCode(), d1.hashCode()); + } + + /** + * Tests that two Digests indicate MATCH when compared. + */ + @Test + public final void testMatchedComparison() { + final int count = 20; + final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(count)); + final Digest d2 = new Digest(DigestAlgorithm.SHA1, getTestDigest(count)); + Assertions.assertEquals(DigestComparisonResultType.MATCH, d1.compare(d2)); + Assertions.assertEquals(DigestComparisonResultType.MATCH, d2.compare(d1)); + } + + /** + * Tests that two Digests have unequal hash code for same + * digest but different algorithm. + */ + @Test + public final void testHashCodeNotEqualAlgorithm() { + final int count = 16; + final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(count)); + final Digest d2 = new Digest(DigestAlgorithm.MD5, getTestDigest(count)); + Assertions.assertNotEquals(d2.hashCode(), d1.hashCode()); + } + + /** + * Tests that two Digests indicate MISMATCH when compared. + */ + @Test + public final void testMismatchAlgorithm() { + final int count = 16; + final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(count)); + final Digest d2 = new Digest(DigestAlgorithm.MD5, getTestDigest(count)); + Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2)); + Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d2.compare(d1)); + } + + /** + * Tests that two Digests have unequal hash code for same + * algorithm but different digest. + */ + @Test + public final void testHashCodeNotEqualDigest() { + final int count = 20; + final byte[] digest = getTestDigest(count); + final Digest d1 = new Digest(DigestAlgorithm.SHA1, digest); + digest[0] += 1; + final Digest d2 = new Digest(DigestAlgorithm.SHA1, digest); + Assertions.assertNotEquals(d2.hashCode(), d1.hashCode()); + Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2)); + } + + /** + * Tests that two Digests are equal for same algorithm and + * digest. + */ + @Test + public final void testEqual() { + final int count = 20; + final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(count)); + final Digest d2 = new Digest(DigestAlgorithm.SHA1, getTestDigest(count)); + Assertions.assertEquals(d2, d1); + } + + /** + * Tests that two Digests are unequal for same digest but + * different algorithm. + */ + @Test + public final void testNotEqualAlgorithm() { + final int count = 16; + final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(count)); + final Digest d2 = new Digest(DigestAlgorithm.MD5, getTestDigest(count)); + Assertions.assertNotEquals(d2, d1); + } + + /** + * Tests that two Digests are unequal for same algorithm but + * different digest. + */ + @Test + public final void testNotEqualDigest() { + final int count = 20; + final byte[] digest = getTestDigest(count); + final Digest d1 = new Digest(DigestAlgorithm.SHA1, digest); + digest[0] += 1; + final Digest d2 = new Digest(DigestAlgorithm.SHA1, digest); + Assertions.assertNotEquals(d2, d1); + } + + /** + * Tests that comparing a null Digest to a Digest indicates an UNKNOWN + * comparison type. + */ + @Test + public final void testCompareToNull() { + final int count = 16; + final Digest d1 = new Digest(DigestAlgorithm.MD2, getTestDigest(count)); + Assertions.assertEquals(DigestComparisonResultType.UNKNOWN, d1.compare(null)); + } + + /** + * Tests that comparing two Digests with hashes with values of zero gives a MATCH + * comparison result. + */ + @Test + public final void testCompareToDigestWithBothZeroizedHash() { + final int count = 20; + final Digest d1 = new Digest(DigestAlgorithm.SHA1, getZeroValueDigest(count)); + final Digest d2 = new Digest(DigestAlgorithm.SHA1, getZeroValueDigest(count)); + Assertions.assertEquals(DigestComparisonResultType.MATCH, d1.compare(d2)); + Assertions.assertEquals(DigestComparisonResultType.MATCH, d2.compare(d1)); + } + + /** + * Tests that comparing two Digests, one with a hash of value zero, gives a MISMATCH + * comparison result. + */ + @Test + public final void testCompareToDigestWithOneZeroizedHash() { + final int count = 20; + final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(count)); + final Digest d2 = new Digest(DigestAlgorithm.SHA1, getZeroValueDigest(count)); + Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2)); + Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d2.compare(d1)); + } + + /** + * Tests that comparing two Digests with a hash of no data gives a MATCH + * comparison result. + */ + @Test + public final void testCompareToDigestWithBothEmptyHash() { + final Digest d1 = new Digest(DigestAlgorithm.SHA1, getEmptySHA1Digest()); + final Digest d2 = new Digest(DigestAlgorithm.SHA1, getEmptySHA1Digest()); + Assertions.assertEquals(DigestComparisonResultType.MATCH, d1.compare(d2)); + Assertions.assertEquals(DigestComparisonResultType.MATCH, d2.compare(d1)); + } + + /** + * Tests that comparing two Digests, one with a hash of no data, gives a MISMATCH + * comparison result. + */ + @Test + public final void testCompareToDigestWithOneEmptyHash() { + final int count = 20; + final Digest d1 = new Digest(DigestAlgorithm.SHA1, getTestDigest(count)); + final Digest d2 = new Digest(DigestAlgorithm.SHA1, getEmptySHA1Digest()); + Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d1.compare(d2)); + Assertions.assertEquals(DigestComparisonResultType.MISMATCH, d2.compare(d1)); + } + + /** + * Tests that if someone tries to recreate a Digest using an invalid String, an error is thrown. + */ + @Test + public final void testFromStringInvalid() { + String invalidDigestString = "SHA1 00000000000000000000"; + Assertions.assertThrows(IllegalArgumentException.class, + () -> Digest.fromString(invalidDigestString)); + } + private byte[] getEmptySHA1Digest() { - return DigestUtils.sha1(new byte[]{}); + return DigestUtils.sha1(new byte[] {}); } } diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/FirmwareInfoTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/FirmwareInfoTest.java index e337399f..5c8aad51 100644 --- a/HIRS_Utils/src/test/java/hirs/data/persist/FirmwareInfoTest.java +++ b/HIRS_Utils/src/test/java/hirs/data/persist/FirmwareInfoTest.java @@ -2,11 +2,11 @@ package hirs.data.persist; import hirs.attestationca.persist.entity.userdefined.info.FirmwareInfo; import org.apache.commons.lang3.StringUtils; -import static hirs.utils.enums.DeviceInfoEnums.NOT_SPECIFIED; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static hirs.utils.enums.DeviceInfoEnums.NOT_SPECIFIED; + /** * FirmwareInfoTest is a unit test class for FirmwareInfo. */ @@ -15,18 +15,20 @@ public class FirmwareInfoTest { private static final String BIOS_VENDOR = "test bios vendor"; private static final String BIOS_VERSION = "test bios version"; private static final String BIOS_RELEASE_DATE = "test bios release date"; + private static final int PRIMARY_SIZE = 257; + private static final int SECONDARY_SIZE = 33; private static final String LONG_BIOS_VENDOR = StringUtils.rightPad( - "test bios vendor", - 257 + BIOS_VENDOR, + PRIMARY_SIZE ); private static final String LONG_BIOS_VERSION = StringUtils.rightPad( - "test bios version", - 257 + BIOS_VERSION, + PRIMARY_SIZE ); private static final String LONG_BIOS_RELEASE_DATE = StringUtils.rightPad( - "test bios release date", - 33 + BIOS_RELEASE_DATE, + SECONDARY_SIZE ); /** @@ -44,8 +46,8 @@ public class FirmwareInfoTest { public final void firmwareInfoNoParams() { FirmwareInfo firmwareInfo = new FirmwareInfo(); Assertions.assertEquals(NOT_SPECIFIED, firmwareInfo.getBiosVendor()); - Assertions.assertEquals(NOT_SPECIFIED,firmwareInfo.getBiosVersion()); - Assertions.assertEquals(NOT_SPECIFIED,firmwareInfo.getBiosReleaseDate()); + Assertions.assertEquals(NOT_SPECIFIED, firmwareInfo.getBiosVersion()); + Assertions.assertEquals(NOT_SPECIFIED, firmwareInfo.getBiosReleaseDate()); } /** diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/HardwareInfoTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/HardwareInfoTest.java index a5ab1f4e..d0ffee83 100644 --- a/HIRS_Utils/src/test/java/hirs/data/persist/HardwareInfoTest.java +++ b/HIRS_Utils/src/test/java/hirs/data/persist/HardwareInfoTest.java @@ -1,12 +1,12 @@ package hirs.data.persist; import hirs.attestationca.persist.entity.userdefined.info.HardwareInfo; -import static hirs.utils.enums.DeviceInfoEnums.NOT_SPECIFIED; - import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static hirs.utils.enums.DeviceInfoEnums.NOT_SPECIFIED; + /** * HardwareInfoTest is a unit test class for HardwareInfo. */ @@ -18,30 +18,32 @@ public class HardwareInfoTest { private static final String SERIAL_NUMBER = "test serial number"; private static final String CHASSIS_SERIAL_NUMBER = "test chassis serial number"; private static final String BASEBOARD_SERIAL_NUMBER = "test baseboard serial number"; + private static final int PRIMARY_SIZE = 257; + private static final int SECONDARY_SIZE = 65; private static final String LONG_MANUFACTURER = StringUtils.rightPad( - "test manufacturer", - 257 + MANUFACTURER, + PRIMARY_SIZE ); private static final String LONG_PRODUCT_NAME = StringUtils.rightPad( - "test product name", - 257 + PRODUCT_NAME, + PRIMARY_SIZE ); private static final String LONG_VERSION = StringUtils.rightPad( - "test version", - 65 + VERSION, + SECONDARY_SIZE ); private static final String LONG_SERIAL_NUMBER = StringUtils.rightPad( - "test serial number", - 257 + SERIAL_NUMBER, + PRIMARY_SIZE ); private static final String LONG_CHASSIS_SERIAL_NUMBER = StringUtils.rightPad( - "test chassis serial number", - 257 + CHASSIS_SERIAL_NUMBER, + PRIMARY_SIZE ); private static final String LONG_BASEBOARD_SERIAL_NUMBER = StringUtils.rightPad( - "test baseboard serial number", - 257 + BASEBOARD_SERIAL_NUMBER, + PRIMARY_SIZE ); /** diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/NetworkInfoTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/NetworkInfoTest.java index f8476597..042f0037 100644 --- a/HIRS_Utils/src/test/java/hirs/data/persist/NetworkInfoTest.java +++ b/HIRS_Utils/src/test/java/hirs/data/persist/NetworkInfoTest.java @@ -1,12 +1,12 @@ package hirs.data.persist; import hirs.attestationca.persist.entity.userdefined.info.NetworkInfo; -import java.net.InetAddress; -import java.net.UnknownHostException; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.net.InetAddress; +import java.net.UnknownHostException; + /** * NetworkInfoTest is a unit test class for NetworkInfo. */ @@ -17,6 +17,15 @@ public class NetworkInfoTest { private static final byte[] MAC_ADDRESS = new byte[] {11, 22, 33, 44, 55, 66}; + private static InetAddress getTestIpAddress() { + try { + final byte[] byteAddress = new byte[] {127, 0, 0, 1}; + return InetAddress.getByAddress(byteAddress); + } catch (UnknownHostException e) { + return null; + } + } + /** * Tests instantiation of a NetworkInfo object. */ @@ -103,14 +112,14 @@ public class NetworkInfoTest { * Tests that hashcodes generated by NetworkInfo objects with different IP * addresses are not equal. * - * @throws UnknownHostException - * in case the InetAddress is not created correctly + * @throws UnknownHostException in case the InetAddress is not created correctly */ @Test public final void testHashCodeNotEqualsIpAddress() throws UnknownHostException { + final byte[] byteAddress = new byte[] {127, 0, 0, 2}; final InetAddress ipAddress2 = - InetAddress.getByAddress(new byte[] {127, 0, 0, 2}); + InetAddress.getByAddress(byteAddress); NetworkInfo ni1 = new NetworkInfo(HOSTNAME, IP_ADDRESS, MAC_ADDRESS); NetworkInfo ni2 = new NetworkInfo(HOSTNAME, ipAddress2, MAC_ADDRESS); Assertions.assertNotEquals(ni2.hashCode(), ni1.hashCode()); @@ -155,13 +164,13 @@ public class NetworkInfoTest { * Tests that two NetworkInfo objects are not equal if they have different * IP addresses. * - * @throws UnknownHostException - * in case InetAddress is not created correctly + * @throws UnknownHostException in case InetAddress is not created correctly */ @Test public final void testNotEqualsIpAddress() throws UnknownHostException { + final byte[] byteAddress = new byte[] {127, 0, 0, 2}; final InetAddress ipAddress2 = - InetAddress.getByAddress(new byte[] {127, 0, 0, 2}); + InetAddress.getByAddress(byteAddress); NetworkInfo ni1 = new NetworkInfo(HOSTNAME, IP_ADDRESS, MAC_ADDRESS); NetworkInfo ni2 = new NetworkInfo(HOSTNAME, ipAddress2, MAC_ADDRESS); Assertions.assertNotEquals(ni2, ni1); @@ -178,12 +187,4 @@ public class NetworkInfoTest { NetworkInfo ni2 = new NetworkInfo(HOSTNAME, IP_ADDRESS, macAddress2); Assertions.assertNotEquals(ni2, ni1); } - - private static InetAddress getTestIpAddress() { - try { - return InetAddress.getByAddress(new byte[] {127, 0, 0, 1}); - } catch (UnknownHostException e) { - return null; - } - } } diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/OSInfoTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/OSInfoTest.java index 20b82abf..39d64863 100644 --- a/HIRS_Utils/src/test/java/hirs/data/persist/OSInfoTest.java +++ b/HIRS_Utils/src/test/java/hirs/data/persist/OSInfoTest.java @@ -1,12 +1,12 @@ package hirs.data.persist; import hirs.attestationca.persist.entity.userdefined.info.OSInfo; -import static hirs.utils.enums.DeviceInfoEnums.NOT_SPECIFIED; - import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static hirs.utils.enums.DeviceInfoEnums.NOT_SPECIFIED; + /** * OSInfoTest is a unit test class for OSInfo. */ @@ -17,10 +17,12 @@ public class OSInfoTest { private static final String OS_ARCH = "test osArch"; private static final String DISTRIBUTION = "test distribution"; private static final String DISTRIBUTION_RELEASE = "test distribution release"; + private static final int PRIMARY_SIZE = 257; + private static final int SECONDARY_SIZE = 33; - private static final String LONG_OS_NAME = StringUtils.rightPad("test os", 257); - private static final String LONG_OS_VERSION = StringUtils.rightPad("test osVersion", 257); - private static final String LONG_OS_ARCH = StringUtils.rightPad("test osArch", 33); + private static final String LONG_OS_NAME = StringUtils.rightPad(OS_NAME, PRIMARY_SIZE); + private static final String LONG_OS_VERSION = StringUtils.rightPad(OS_VERSION, PRIMARY_SIZE); + private static final String LONG_OS_ARCH = StringUtils.rightPad(OS_ARCH, SECONDARY_SIZE); /** * Tests instantiation of an OSInfo object. @@ -63,7 +65,7 @@ public class OSInfoTest { @Test public final void osNameNullTest() { Assertions.assertThrows(IllegalArgumentException.class, () -> - new OSInfo(null, OS_VERSION, OS_ARCH, DISTRIBUTION, DISTRIBUTION_RELEASE)); + new OSInfo(null, OS_VERSION, OS_ARCH, DISTRIBUTION, DISTRIBUTION_RELEASE)); } /** @@ -72,7 +74,7 @@ public class OSInfoTest { @Test public final void osVersionNullTest() { Assertions.assertThrows(IllegalArgumentException.class, () -> - new OSInfo(OS_NAME, null, OS_ARCH, DISTRIBUTION, DISTRIBUTION_RELEASE)); + new OSInfo(OS_NAME, null, OS_ARCH, DISTRIBUTION, DISTRIBUTION_RELEASE)); } /** @@ -81,7 +83,7 @@ public class OSInfoTest { @Test public final void osArchNullTest() { Assertions.assertThrows(IllegalArgumentException.class, () -> - new OSInfo(OS_NAME, OS_VERSION, null, DISTRIBUTION, DISTRIBUTION_RELEASE)); + new OSInfo(OS_NAME, OS_VERSION, null, DISTRIBUTION, DISTRIBUTION_RELEASE)); } /** @@ -108,7 +110,7 @@ public class OSInfoTest { @Test public final void osArchLongTest() { Assertions.assertThrows(IllegalArgumentException.class, () -> - new OSInfo(OS_NAME, OS_VERSION, LONG_OS_ARCH, DISTRIBUTION, DISTRIBUTION_RELEASE)); + new OSInfo(OS_NAME, OS_VERSION, LONG_OS_ARCH, DISTRIBUTION, DISTRIBUTION_RELEASE)); } /** diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/package-info.java b/HIRS_Utils/src/test/java/hirs/data/persist/package-info.java new file mode 100644 index 00000000..387d0845 --- /dev/null +++ b/HIRS_Utils/src/test/java/hirs/data/persist/package-info.java @@ -0,0 +1 @@ +package hirs.data.persist; diff --git a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/UefiProcessingTest.java b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/UefiProcessingTest.java index 183af293..f069208e 100644 --- a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/UefiProcessingTest.java +++ b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/UefiProcessingTest.java @@ -1,25 +1,29 @@ package hirs.tpm.eventlog.uefi; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; - import com.eclipsesource.json.JsonObject; +import hirs.utils.HexUtils; import hirs.utils.JsonUtils; -import hirs.utils.tpm.eventlog.uefi.*; +import hirs.utils.tpm.eventlog.uefi.UefiDevicePath; +import hirs.utils.tpm.eventlog.uefi.UefiFirmware; +import hirs.utils.tpm.eventlog.uefi.UefiGuid; +import hirs.utils.tpm.eventlog.uefi.UefiPartition; +import hirs.utils.tpm.eventlog.uefi.UefiVariable; import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import hirs.utils.HexUtils; - import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + /** * Class for testing TCG Event Log processing of UEFI defined Data. */ @@ -61,7 +65,7 @@ public class UefiProcessingTest { * @throws IOException when processing the test fails. * @throws NoSuchAlgorithmException if non TCG Algorithm is encountered. * @throws CertificateException if parsing issue for X509 cert is encountered. - * @throws URISyntaxException File location exception + * @throws URISyntaxException File location exception */ @Test public final void testUefiVariables() throws IOException, @@ -70,7 +74,7 @@ public class UefiProcessingTest { Path jsonPath = Paths.get(this.getClass() .getResource(JSON_FILE).toURI()); String uefiTxt = IOUtils.toString(this.getClass().getResourceAsStream(UEFI_VARIABLE_BOOT), - "UTF-8"); + StandardCharsets.UTF_8); byte[] uefiVariableBytes = HexUtils.hexStringToByteArray(uefiTxt); UefiVariable uefiVariable = new UefiVariable(uefiVariableBytes); UefiGuid guid = uefiVariable.getUefiVarGuid(); @@ -83,7 +87,7 @@ public class UefiProcessingTest { uefiTxt = IOUtils.toString(this.getClass() .getResourceAsStream(UEFI_VARIABLE_BOOT_SECURE_BOOT), - "UTF-8"); + StandardCharsets.UTF_8); uefiVariableBytes = HexUtils.hexStringToByteArray(uefiTxt); uefiVariable = new UefiVariable(uefiVariableBytes); guid = uefiVariable.getUefiVarGuid(); @@ -94,7 +98,7 @@ public class UefiProcessingTest { Assertions.assertEquals("SecureBoot", varName); uefiTxt = IOUtils.toString(this.getClass().getResourceAsStream( - UEFI_VARIABLE_BOOT_DRIVER_CONFIG_KEK), "UTF-8"); + UEFI_VARIABLE_BOOT_DRIVER_CONFIG_KEK), StandardCharsets.UTF_8); uefiVariableBytes = HexUtils.hexStringToByteArray(uefiTxt); uefiVariable = new UefiVariable(uefiVariableBytes); varName = uefiVariable.getEfiVarName(); @@ -107,7 +111,7 @@ public class UefiProcessingTest { * @throws IOException when processing the test fails. * @throws NoSuchAlgorithmException if non TCG Algorithm is encountered. * @throws CertificateException if parsing issue for X509 cert is encountered. - * @throws URISyntaxException File location exception + * @throws URISyntaxException File location exception */ @Test public final void testUefiPartiton() throws IOException, @@ -116,7 +120,7 @@ public class UefiProcessingTest { Path jsonPath = Paths.get(this.getClass() .getResource(JSON_FILE).toURI()); String uefiTxt = IOUtils.toString(this.getClass().getResourceAsStream(UEFI_GPT_EVENT), - "UTF-8"); + StandardCharsets.UTF_8); byte[] uefiPartitionBytes = HexUtils.hexStringToByteArray(uefiTxt); UefiPartition gptPart = new UefiPartition(uefiPartitionBytes); String gptPartName = gptPart.getPartitionName(); @@ -143,29 +147,33 @@ public class UefiProcessingTest { CertificateException, NoSuchAlgorithmException { LOGGER.debug("Testing the parsing of Uefi Firmware Blob"); String uefiTxt = IOUtils.toString(this.getClass() - .getResourceAsStream(UEFI_FW_BLOB), "UTF-8"); + .getResourceAsStream(UEFI_FW_BLOB), StandardCharsets.UTF_8); byte[] uefiFwBlobBytes = HexUtils.hexStringToByteArray(uefiTxt); UefiFirmware uefiFWBlob = new UefiFirmware(uefiFwBlobBytes); int fwAddress = uefiFWBlob.getPhysicalBlobAddress(); int fwLength = uefiFWBlob.getBlobLength(); - Assertions.assertEquals(1797287936, fwAddress); - Assertions.assertEquals(851968, fwLength); + + final int expectedFwAddress = 1797287936; + Assertions.assertEquals(expectedFwAddress, fwAddress); + + final int expectedFwLength = 851968; + Assertions.assertEquals(expectedFwLength, fwLength); } /** * Tests the processing of a UEFI defined Device Path. * - * @throws IOException when processing the test fails. + * @throws IOException when processing the test fails. * @throws URISyntaxException File location exception */ @Test public final void testUefiDevicePath() throws IOException, URISyntaxException { LOGGER.debug("Testing the parsing of Uefi Device Path"); String uefiTxt = IOUtils.toString(this.getClass().getResourceAsStream(UEFI_DEVICE_PATH), - "UTF-8"); + StandardCharsets.UTF_8); byte[] uefiFwBlobBytes = HexUtils.hexStringToByteArray(uefiTxt); UefiDevicePath uefiDevPath = new UefiDevicePath(uefiFwBlobBytes); String devPathType = uefiDevPath.getType(); Assertions.assertEquals("Media Device Path", devPathType); } -} \ No newline at end of file +} diff --git a/HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/package-info.java b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/package-info.java new file mode 100644 index 00000000..8762db47 --- /dev/null +++ b/HIRS_Utils/src/test/java/hirs/tpm/eventlog/uefi/package-info.java @@ -0,0 +1 @@ +package hirs.tpm.eventlog.uefi; diff --git a/HIRS_Utils/src/test/java/hirs/utils/BouncyCastleUtilsTest.java b/HIRS_Utils/src/test/java/hirs/utils/BouncyCastleUtilsTest.java index 14116536..6588051c 100644 --- a/HIRS_Utils/src/test/java/hirs/utils/BouncyCastleUtilsTest.java +++ b/HIRS_Utils/src/test/java/hirs/utils/BouncyCastleUtilsTest.java @@ -2,8 +2,9 @@ package hirs.utils; import org.apache.logging.log4j.util.Strings; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertTrue; + import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Tests methods in the (@link BouncyCastleUtils) utility class. @@ -46,4 +47,4 @@ public class BouncyCastleUtilsTest { assertFalse(BouncyCastleUtils.x500NameCompare( MALFORMED_RDN_STRING, MALFORMED_RDN_STRING)); } -} \ No newline at end of file +} diff --git a/HIRS_Utils/src/test/java/hirs/utils/HexUtilsTest.java b/HIRS_Utils/src/test/java/hirs/utils/HexUtilsTest.java index 9e3ba416..11fd72a8 100644 --- a/HIRS_Utils/src/test/java/hirs/utils/HexUtilsTest.java +++ b/HIRS_Utils/src/test/java/hirs/utils/HexUtilsTest.java @@ -1,6 +1,7 @@ package hirs.utils; import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -14,11 +15,10 @@ public class HexUtilsTest { */ @Test public void testHexStringToByteArray() { - String s = "abcd1234"; - byte[] target = {-85, -51, 18, 52}; - - byte[] b = HexUtils.hexStringToByteArray(s); - assertArrayEquals(b, target); + final String testString = "abcd1234"; + final byte[] expectedBytes = {-85, -51, 18, 52}; + final byte[] actualBytes = HexUtils.hexStringToByteArray(testString); + assertArrayEquals(expectedBytes, actualBytes); } /** @@ -26,11 +26,10 @@ public class HexUtilsTest { */ @Test public void testByteArrayToHexString() { - String target = "abcd1234"; - byte[] b = {-85, -51, 18, 52}; - - String s = HexUtils.byteArrayToHexString(b); - assertEquals(s, target); + final byte[] byteArray = {-85, -51, 18, 52}; + final String expectedString = "abcd1234"; + final String actualString = HexUtils.byteArrayToHexString(byteArray); + assertEquals(expectedString, actualString); } /** @@ -38,11 +37,10 @@ public class HexUtilsTest { */ @Test public void testByteArrayToHexStringConditional() { - String target = "abcd0100"; - byte[] b = {-85, -51, 1, 0}; - - String s = HexUtils.byteArrayToHexString(b); - assertEquals(s, target); + final byte[] byteArray = {-85, -51, 1, 0}; + final String expectedHexString = "abcd0100"; + final String actualHexString = HexUtils.byteArrayToHexString(byteArray); + assertEquals(expectedHexString, actualHexString); } /** @@ -50,9 +48,10 @@ public class HexUtilsTest { */ @Test public void testHexToInt() { - String s = "ff"; - Integer i = HexUtils.hexToInt(s); - assertEquals((int) i, HexUtils.FF_BYTE); + final String testString = "ff"; + final int expectedInt = HexUtils.FF_BYTE; + final Integer actualInt = HexUtils.hexToInt(testString); + assertEquals(expectedInt, (int) actualInt); } /** @@ -60,14 +59,11 @@ public class HexUtilsTest { */ @Test public void testSubarray() { - byte[] b = {-85, -51, 18, 52}; - byte[] target = {-51, 18}; - - byte[] sub = HexUtils.subarray(b, 1, 2); - - assertArrayEquals(sub, target); + final byte[] b = {-85, -51, 18, 52}; + final byte[] expectedSubArray = {-51, 18}; + final byte[] actualSubArray = HexUtils.subarray(b, 1, 2); + assertArrayEquals(expectedSubArray, actualSubArray); } - } diff --git a/HIRS_Utils/src/test/java/hirs/utils/StringValidatorTest.java b/HIRS_Utils/src/test/java/hirs/utils/StringValidatorTest.java index 18efdbc7..200d1e25 100644 --- a/HIRS_Utils/src/test/java/hirs/utils/StringValidatorTest.java +++ b/HIRS_Utils/src/test/java/hirs/utils/StringValidatorTest.java @@ -1,11 +1,12 @@ package hirs.utils; import org.apache.logging.log4j.Logger; -import org.mockito.Mockito; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertNull; +import org.mockito.Mockito; + import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.times; /** @@ -114,10 +115,10 @@ public class StringValidatorTest { @Test public void testValidateMaxLengthFailOnLongString() { assertThrows(IllegalArgumentException.class, () -> - assertEquals( - StringValidator.check(NONEMPTY_VALUE, FIELD_NAME).maxLength(SMALL_LENGTH).getValue(), - NONEMPTY_VALUE - )); + assertEquals( + StringValidator.check(NONEMPTY_VALUE, FIELD_NAME).maxLength(SMALL_LENGTH).getValue(), + NONEMPTY_VALUE + )); } /** @@ -138,8 +139,8 @@ public class StringValidatorTest { @Test public void testValidateSeveralConditionsFailOnLast() { assertThrows(IllegalArgumentException.class, () -> - StringValidator.check(NONEMPTY_VALUE, FIELD_NAME) - .notNull().notBlank().maxLength(SMALL_LENGTH)); + StringValidator.check(NONEMPTY_VALUE, FIELD_NAME) + .notNull().notBlank().maxLength(SMALL_LENGTH)); } /** @@ -155,4 +156,4 @@ public class StringValidatorTest { } Mockito.verify(mockLogger, times(1)).error(Mockito.anyString()); } -} \ No newline at end of file +} diff --git a/HIRS_Utils/src/test/java/hirs/utils/package-info.java b/HIRS_Utils/src/test/java/hirs/utils/package-info.java new file mode 100644 index 00000000..361ebc74 --- /dev/null +++ b/HIRS_Utils/src/test/java/hirs/utils/package-info.java @@ -0,0 +1 @@ +package hirs.utils; diff --git a/HIRS_Utils/src/test/java/hirs/utils/tpm/eventlog/TCGEventLogTest.java b/HIRS_Utils/src/test/java/hirs/utils/tpm/eventlog/TCGEventLogTest.java index 7fe0aefd..34f692ba 100644 --- a/HIRS_Utils/src/test/java/hirs/utils/tpm/eventlog/TCGEventLogTest.java +++ b/HIRS_Utils/src/test/java/hirs/utils/tpm/eventlog/TCGEventLogTest.java @@ -1,20 +1,20 @@ package hirs.utils.tpm.eventlog; +import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + import java.io.IOException; import java.io.InputStream; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.util.Arrays; -import org.apache.commons.io.IOUtils; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; +import static hirs.utils.tpm.eventlog.TCGEventLog.PCR_COUNT; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -36,103 +36,117 @@ public class TCGEventLogTest { @BeforeAll public static final void setup() { LOGGER.debug("retrieving session factory"); - } /** * Closes the SessionFactory from setup. */ @AfterAll - public static final void tearDown() { - LOGGER.debug("closing session factory"); - } + public static final void tearDown() { + LOGGER.debug("closing session factory"); + } - /** - * Tests the processing of a crypto agile event log. - * @throws IOException when processing the test fails - * @throws NoSuchAlgorithmException if an unknown algorithm is encountered. - * @throws CertificateException if a certificate fails to parse. - */ + /** + * Tests the processing of a crypto agile event log. + * + * @throws IOException when processing the test fails + * @throws NoSuchAlgorithmException if an unknown algorithm is encountered. + * @throws CertificateException if a certificate fails to parse. + */ @Test public final void testCryptoAgileTCGEventLog() throws IOException, CertificateException, - NoSuchAlgorithmException { - LOGGER.debug("Testing the parsing of a Crypto Agile formatted TCG Event Log"); - InputStream log, pcrs; - boolean testPass = true; - log = this.getClass().getResourceAsStream(DEFAULT_EVENT_LOG); - byte[] rawLogBytes = IOUtils.toByteArray(log); - TCGEventLog evlog = new TCGEventLog(rawLogBytes, false, false, false); - String[] pcrFromLog = evlog.getExpectedPCRValues(); - pcrs = this.getClass().getResourceAsStream(DEFAULT_EXPECTED_PCRS); - Object[] pcrObj = IOUtils.readLines(pcrs, "UTF-8").toArray(); - String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class); - - // Test 1 get all PCRs - for (int i = 0; i < 24; i++) { - if (pcrFromLog[i].compareToIgnoreCase(pcrTxt[i]) != 0) { - testPass = false; - LOGGER.error("\ntestTCGEventLogProcessorParser error with PCR " + i); - } - } - assertTrue(testPass); - - // Test 2 get an individual PCR - String pcr3 = evlog.getExpectedPCRValue(3); - assertThat(pcrFromLog[3], equalTo(pcr3)); + NoSuchAlgorithmException { + LOGGER.debug("Testing the parsing of a Crypto Agile formatted TCG Event Log"); - // Test 3 check the Algorithm String Identifier used in the log - String algStr = evlog.getEventLogHashAlgorithm(); - assertThat("TPM_ALG_SHA256", equalTo(algStr)); - // Test 4 check the Algorithm # Identifier used in the log - int id = evlog.getEventLogHashAlgorithmID(); - assertThat(TcgTpmtHa.TPM_ALG_SHA256, equalTo(id)); - - LOGGER.debug("OK. Parsing of a Crypto Agile Format Success"); + try { + // setup + final InputStream log = this.getClass().getResourceAsStream(DEFAULT_EVENT_LOG); + final InputStream pcrs = this.getClass().getResourceAsStream(DEFAULT_EXPECTED_PCRS); + final byte[] rawLogBytes = IOUtils.toByteArray(log); + final TCGEventLog evlog = new TCGEventLog(rawLogBytes, false, false, false); + final String[] pcrFromLog = evlog.getExpectedPCRValues(); + final Object[] pcrObj = IOUtils.readLines(pcrs, "UTF-8").toArray(); + final String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class); + + boolean testPass = true; + + // Test 1 get all PCRs + for (int i = 0; i < PCR_COUNT; i++) { + if (pcrFromLog[i].compareToIgnoreCase(pcrTxt[i]) != 0) { + testPass = false; + LOGGER.error("\ntestTCGEventLogProcessorParser error with PCR {}", i); + } + } + assertTrue(testPass); + + // Test 2 get an individual PCR + final int pcrIndex = 3; + String pcr3 = evlog.getExpectedPCRValue(pcrIndex); + assertThat(pcrFromLog[pcrIndex], equalTo(pcr3)); + + // Test 3 check the Algorithm String Identifier used in the log + String algStr = evlog.getEventLogHashAlgorithm(); + assertThat("TPM_ALG_SHA256", equalTo(algStr)); + + // Test 4 check the Algorithm # Identifier used in the log + int id = evlog.getEventLogHashAlgorithmID(); + assertThat(TcgTpmtHa.TPM_ALG_SHA256, equalTo(id)); + + LOGGER.debug("OK. Parsing of a Crypto Agile Format Success"); + } catch (Throwable throwable) { + throw throwable; + } } /** * Tests the processing of a SHA1 formatted Event log. - * @throws IOException when processing the test fails + * + * @throws IOException when processing the test fails * @throws NoSuchAlgorithmException if an unknown algorithm is encountered. - * @throws CertificateException if a certificate fails to parse. + * @throws CertificateException if a certificate fails to parse. */ @Test public final void testSHA1TCGEventLog() throws IOException, CertificateException, - NoSuchAlgorithmException { - LOGGER.debug("Testing the parsing of a SHA1 formated TCG Event Log"); - InputStream log, pcrs; - boolean testPass = true; - log = this.getClass().getResourceAsStream(SHA1_EVENT_LOG); - byte[] rawLogBytes = IOUtils.toByteArray(log); - TCGEventLog evlog = new TCGEventLog(rawLogBytes, false, false, false); - String[] pcrFromLog = evlog.getExpectedPCRValues(); - pcrs = this.getClass().getResourceAsStream(SHA1_EXPECTED_PCRS); - Object[] pcrObj = IOUtils.readLines(pcrs, "UTF-8").toArray(); - String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class); - - // Test 1 get all PCRs - for (int i = 0; i < 24; i++) { - if (pcrFromLog[i].compareToIgnoreCase(pcrTxt[i]) != 0) { - testPass = false; - LOGGER.error("\ntestTCGEventLogProcessorParser error with PCR " + i); - } - } - assertTrue(testPass); - - // Test 2 get an individual PCR - String pcr0 = evlog.getExpectedPCRValue(0); - assertThat(pcrFromLog[0], equalTo(pcr0)); - - // Test 3 check the Algorithm String Identifier used in the log - String algStr = evlog.getEventLogHashAlgorithm(); - assertThat("TPM_ALG_SHA1", equalTo(algStr)); + NoSuchAlgorithmException { + LOGGER.debug("Testing the parsing of a SHA1 formated TCG Event Log"); - // Test 4 check the Algorithm # Identifier used in the log - int id = evlog.getEventLogHashAlgorithmID(); - assertThat(TcgTpmtHa.TPM_ALG_SHA1, equalTo(id)); - - LOGGER.debug("OK. Parsing of a SHA1 formatted TCG Event Log Success"); - } - + try { + // setup + final InputStream log = this.getClass().getResourceAsStream(SHA1_EVENT_LOG); + final InputStream pcrs = this.getClass().getResourceAsStream(SHA1_EXPECTED_PCRS); + final byte[] rawLogBytes = IOUtils.toByteArray(log); + final TCGEventLog evlog = new TCGEventLog(rawLogBytes, false, false, false); + final String[] pcrFromLog = evlog.getExpectedPCRValues(); + final Object[] pcrObj = IOUtils.readLines(pcrs, "UTF-8").toArray(); + final String[] pcrTxt = Arrays.copyOf(pcrObj, pcrObj.length, String[].class); + + boolean testPass = true; + + // Test 1 get all PCRs + for (int i = 0; i < PCR_COUNT; i++) { + if (pcrFromLog[i].compareToIgnoreCase(pcrTxt[i]) != 0) { + testPass = false; + LOGGER.error("\ntestTCGEventLogProcessorParser error with PCR {}", i); + } + } + assertTrue(testPass); + + // Test 2 get an individual PCR + String pcr0 = evlog.getExpectedPCRValue(0); + assertThat(pcrFromLog[0], equalTo(pcr0)); + + // Test 3 check the Algorithm String Identifier used in the log + String algStr = evlog.getEventLogHashAlgorithm(); + assertThat("TPM_ALG_SHA1", equalTo(algStr)); + + // Test 4 check the Algorithm # Identifier used in the log + int id = evlog.getEventLogHashAlgorithmID(); + assertThat(TcgTpmtHa.TPM_ALG_SHA1, equalTo(id)); + + LOGGER.debug("OK. Parsing of a SHA1 formatted TCG Event Log Success"); + } catch (Throwable throwable) { + throw throwable; + } + } } diff --git a/HIRS_Utils/src/test/java/hirs/utils/tpm/eventlog/package-info.java b/HIRS_Utils/src/test/java/hirs/utils/tpm/eventlog/package-info.java new file mode 100644 index 00000000..979c6b4f --- /dev/null +++ b/HIRS_Utils/src/test/java/hirs/utils/tpm/eventlog/package-info.java @@ -0,0 +1 @@ +package hirs.utils.tpm.eventlog; diff --git a/build.gradle b/build.gradle index 5cb5860f..20ff3ab6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,4 @@ import java.util.concurrent.TimeUnit -import org.gradle.api.tasks.Copy plugins { // Apply the application plugin to add support for building a CLI application in Java. @@ -8,7 +7,7 @@ plugins { } // Global checkstyle file - ext.checkstyleConfigFile = new File(rootDir, "/config/checkstyle/sun_checks.xml") +ext.checkstyleConfigFile = new File(rootDir, "/config/checkstyle/sun_checks.xml") subprojects { apply plugin: "com.github.spotbugs" @@ -19,13 +18,12 @@ subprojects { tasks.withType(com.github.spotbugs.snom.SpotBugsTask) { reports { - html { - enabled = true - } + html.required = true } } } + dependencies { repositories { // Use Maven Central for resolving dependencies. @@ -36,10 +34,10 @@ dependencies { def projectVersion = rootProject.file('VERSION').text.trim() def buildTime = { -> - Date latestdate = new Date(); - def time = latestdate.getTime(); - long seconds = TimeUnit.MILLISECONDS.toSeconds(time); - return seconds; + Date latestdate = new Date() + def time = latestdate.getTime() + long seconds = TimeUnit.MILLISECONDS.toSeconds(time) + return seconds } def gitHash = { -> diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 503e7bab..cf854c69 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -109,7 +109,10 @@ - + + + @@ -163,10 +166,17 @@ - + + + - + + + + +