Initial set of changes for #642 that are fixes for HIRS_AttestationCA.

In addition, this and the following pushes will have changes for #651
because spot bugs doesn't like how Lombok handles hashCode and equals
This commit is contained in:
Cyrus 2023-12-22 07:44:47 -05:00
parent 0432646445
commit 0d25599c80
13 changed files with 98 additions and 38 deletions

View File

@ -2,17 +2,8 @@
<!-- Docs at http://findbugs.sourceforge.net/manual/filter.html -->
<FindBugsFilter>
<Match>
<Package name="~hirs\.attestationca.*" />
</Match>
<Match>
<!-- https://github.com/spotbugs/spotbugs/pull/2748 -->
<Bug pattern="CT_CONSTRUCTOR_THROW" />
<Package name="~hirs\.attestationca\.configuration*" />
</Match>
<!-- <Match>-->
<!-- &lt;!&ndash; To suppress false warnings in unit-tests for lambdas not using return values. &ndash;&gt;-->
<!-- <Package name="~com\.company\.service\.interfaces\.types\.contacts"/>-->
<!-- <Bug pattern="RV_RETURN_VALUE_IGNORED"/>-->
<!-- </Match>-->
</FindBugsFilter>

View File

@ -70,7 +70,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
/**
@ -593,8 +592,8 @@ public abstract class Certificate extends ArchivableEntity {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
parsedX509Cert = (X509Certificate) cf.generateCertificate(certInputStream);
return parsedX509Cert;
} catch (CertificateException e) {
throw new IOException("Cannot construct X509Certificate from the input stream", e);
} catch (CertificateException cEx) {
throw new IOException("Cannot construct X509Certificate from the input stream", cEx);
}
}

View File

@ -22,23 +22,26 @@ import java.sql.Timestamp;
@Entity
@Table(name = "Device")
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Device extends AbstractEntity {
@Getter
@Column(name = "name", unique = true)
private String name;
@Getter
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER,
optional = true, orphanRemoval = true)
private DeviceInfoReport deviceInfo;
@Getter
@Column
@Enumerated(EnumType.ORDINAL)
private HealthStatus healthStatus;
@Getter
@Column
@Enumerated(EnumType.ORDINAL)
private AppraisalStatus.Status supplyChainValidationStatus;
@ -49,12 +52,15 @@ public class Device extends AbstractEntity {
@Column(name = "last_report_timestamp")
private Timestamp lastReportTimestamp;
@Getter
@Column(name = "is_state_overridden")
private boolean isStateOverridden;
@Getter
@Column(name = "state_override_reason")
private String overrideReason;
@Getter
@Column(name = "summary_id")
private String summaryId;
@ -68,6 +74,14 @@ public class Device extends AbstractEntity {
}
}
/**
* Getter for the report time stamp.
* @return a cloned version
*/
public Timestamp getLastReportTimestamp() {
return (Timestamp) lastReportTimestamp.clone();
}
public String toString() {
return String.format("Device Name: %s%nStatus: %s%nSummary: %s",
name, healthStatus.getStatus(),

View File

@ -8,6 +8,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.io.Serializable;
import java.math.BigInteger;
/**
@ -24,7 +25,7 @@ import java.math.BigInteger;
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter @Setter
@Embeddable
public class TPMSecurityAssertions {
public class TPMSecurityAssertions implements Serializable {
/**
* A type to handle the different endorsement key generation types used in the TPM

View File

@ -7,6 +7,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigInteger;
/**
@ -23,7 +24,7 @@ import java.math.BigInteger;
@NoArgsConstructor(access= AccessLevel.PROTECTED)
@Getter
@Embeddable
public class TPMSpecification {
public class TPMSpecification implements Serializable {
@Column
private String family;

View File

@ -4,7 +4,6 @@ import hirs.attestationca.persist.entity.userdefined.certificate.attributes.Comp
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentClass;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.ComponentIdentifier;
import hirs.attestationca.persist.entity.userdefined.certificate.attributes.URIReference;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.bouncycastle.asn1.ASN1Boolean;
@ -16,6 +15,7 @@ import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERUTF8String;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@ -39,7 +39,6 @@ import java.util.stream.Collectors;
*/
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
public class ComponentIdentifierV2 extends ComponentIdentifier {
private static final int MANDATORY_ELEMENTS = 3;
@ -200,6 +199,24 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
return true;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
ComponentIdentifierV2 that = (ComponentIdentifierV2) o;
return Objects.equals(componentClass, that.componentClass)
&& Objects.equals(certificateIdentifier, that.certificateIdentifier)
&& Objects.equals(componentPlatformUri, that.componentPlatformUri)
&& attributeStatus == that.attributeStatus;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), componentClass,
certificateIdentifier, componentPlatformUri, attributeStatus);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();

View File

@ -198,8 +198,12 @@ public class BaseReferenceManifest extends ReferenceManifest {
* and tagId attributes, otherwise a generic error message is printed.
*
*/
private Element getDirectoryTag() {
return getDirectoryTag(new ByteArrayInputStream(getRimBytes()));
private Element getDirectoryTag(final byte[] rimBytes) {
if (rimBytes == null || rimBytes.length == 0) {
return getDirectoryTag(new ByteArrayInputStream(getRimBytes()));
} else {
return getDirectoryTag(new ByteArrayInputStream(rimBytes));
}
}
/**
@ -238,7 +242,7 @@ public class BaseReferenceManifest extends ReferenceManifest {
*
*/
public List<SwidResource> getFileResources(final byte[] rimBytes) {
Element directoryTag = getDirectoryTag(new ByteArrayInputStream(rimBytes));
Element directoryTag = getDirectoryTag(rimBytes);
List<SwidResource> validHashes = new ArrayList<>();
NodeList fileNodeList = directoryTag.getChildNodes();
Element file = null;

View File

@ -9,7 +9,6 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
@ -27,7 +26,6 @@ import java.util.Collection;
* however this is the live log from the client.
*/
@Log4j2
@EqualsAndHashCode(callSuper=false)
@Entity
public class EventLogMeasurements extends ReferenceManifest {
@ -114,4 +112,22 @@ public class EventLogMeasurements extends ReferenceManifest {
return new ArrayList<>();
}
@Override
public boolean equals(final Object object) {
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
EventLogMeasurements that = (EventLogMeasurements) object;
return this.getHexDecHash().equals(that.getHexDecHash());
}
@Override
public int hashCode() {
return super.hashCode();
}
}

View File

@ -110,6 +110,14 @@ public class ReferenceDigestValue extends AbstractEntity {
this.contentBlob = Arrays.clone(contentBlob);
}
/**
* the object that contains the raw bytes for this RDV.
* @return the raw bytes
*/
public byte[] getContentBlob() {
return Arrays.clone(contentBlob);
}
/**
* Helper method to update the attributes of this object.
* @param support the associated RIM.

View File

@ -70,6 +70,7 @@ public final class ProvisionUtils {
private static final String AK_NAME_PREFIX = "000b";
private static final String AK_NAME_HASH_PREFIX =
"0001000b00050072000000100014000b0800000000000100";
private static final SecureRandom random = new SecureRandom();
/**
* Helper method to parse a byte array into an {@link hirs.attestationca.configuration.provisionerTpm2.ProvisionerTpm2.IdentityClaim}.
@ -183,7 +184,7 @@ public final class ProvisionUtils {
case OAEP:
OAEPParameterSpec spec =
new OAEPParameterSpec("Sha1", "MGF1", MGF1ParameterSpec.SHA1,
new PSource.PSpecified("".getBytes()));
new PSource.PSpecified("".getBytes(StandardCharsets.UTF_8)));
cipher.init(Cipher.PRIVATE_KEY, privateKey, spec);
break;
@ -283,7 +284,7 @@ public final class ProvisionUtils {
// encrypt seed with pubEk
Cipher asymCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
OAEPParameterSpec oaepSpec = new OAEPParameterSpec("SHA-256", "MGF1",
MGF1ParameterSpec.SHA256, new PSource.PSpecified("IDENTITY\0".getBytes()));
MGF1ParameterSpec.SHA256, new PSource.PSpecified("IDENTITY\0".getBytes(StandardCharsets.UTF_8)));
asymCipher.init(Cipher.PUBLIC_KEY, ek, oaepSpec);
asymCipher.update(seed);
byte[] encSeed = asymCipher.doFinal();
@ -371,7 +372,7 @@ public final class ProvisionUtils {
// encrypt the asymmetric contents and return
OAEPParameterSpec oaepSpec =
new OAEPParameterSpec("Sha1", "MGF1", MGF1ParameterSpec.SHA1,
new PSource.PSpecified("TCPA".getBytes()));
new PSource.PSpecified("TCPA".getBytes(StandardCharsets.UTF_8)));
// initialize the asymmetric cipher using the default OAEP transformation
Cipher cipher = Cipher.getInstance(EncryptionScheme.OAEP.toString());
@ -545,7 +546,7 @@ public final class ProvisionUtils {
if (label.charAt(label.length() - 1) != "\0".charAt(0)) {
labelWithEnding = label + "\0";
}
byte[] labelBytes = labelWithEnding.getBytes();
byte[] labelBytes = labelWithEnding.getBytes(StandardCharsets.UTF_8);
b = ByteBuffer.allocate(4);
b.putInt(sizeInBytes * 8);
byte[] desiredSizeInBits = b.array();
@ -630,7 +631,6 @@ public final class ProvisionUtils {
*/
public static byte[] generateRandomBytes(final int numberOfBytes) {
byte[] bytes = new byte[numberOfBytes];
SecureRandom random = new SecureRandom();
random.nextBytes(bytes);
return bytes;
}

View File

@ -12,8 +12,6 @@ import hirs.attestationca.persist.entity.userdefined.report.DeviceInfoReport;
import hirs.attestationca.persist.enums.AppraisalStatus;
import hirs.attestationca.persist.util.PciIds;
import hirs.utils.enums.DeviceInfoEnums;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
@ -44,10 +42,24 @@ import static hirs.attestationca.persist.enums.AppraisalStatus.Status.PASS;
@Log4j2
public class CertificateAttributeScvValidator extends SupplyChainCredentialValidator {
@Setter
@Getter
private static List<ComponentResult> componentResultList = new LinkedList<>();
/**
* Setter for the list of components to verify.
* @param componentResultList list object for the components
*/
public void setComponentResultList(final List<ComponentResult> componentResultList) {
this.componentResultList = componentResultList.stream().toList();
}
/**
* Getter for the list of components to verify.
* @return a collection of components
*/
public static List<ComponentResult> getComponentResultList() {
return Collections.unmodifiableList(componentResultList);
}
/**
* Checks if the delta credential's attributes are valid.
* @param deltaPlatformCredential the delta credential to verify

View File

@ -19,6 +19,7 @@ import hirs.utils.tpm.eventlog.TpmPcrEvent;
import lombok.extern.log4j.Log4j2;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
@ -178,7 +179,8 @@ public class FirmwareScvValidator extends SupplyChainCredentialValidator {
if (baseline.length > 0) {
String pcrContent = "";
pcrContent = new String(device.getDeviceInfo().getTpmInfo().getPcrValues());
pcrContent = new String(device.getDeviceInfo().getTpmInfo().getPcrValues(),
StandardCharsets.UTF_8);
if (pcrContent.isEmpty()) {
fwStatus = new AppraisalStatus(FAIL,

View File

@ -9,10 +9,5 @@
<Bug pattern="CT_CONSTRUCTOR_THROW" />
</Match>
<!-- <Match>-->
<!-- &lt;!&ndash; To suppress false warnings in unit-tests for lambdas not using return values. &ndash;&gt;-->
<!-- <Package name="~com\.company\.service\.interfaces\.types\.contacts"/>-->
<!-- <Bug pattern="RV_RETURN_VALUE_IGNORED"/>-->
<!-- </Match>-->
</FindBugsFilter>