mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-02-20 17:52:47 +00:00
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:
parent
0432646445
commit
0d25599c80
@ -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>-->
|
||||
<!-- <!– To suppress false warnings in unit-tests for lambdas not using return values. –>-->
|
||||
<!-- <Package name="~com\.company\.service\.interfaces\.types\.contacts"/>-->
|
||||
<!-- <Bug pattern="RV_RETURN_VALUE_IGNORED"/>-->
|
||||
<!-- </Match>-->
|
||||
</FindBugsFilter>
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -9,10 +9,5 @@
|
||||
<Bug pattern="CT_CONSTRUCTOR_THROW" />
|
||||
</Match>
|
||||
|
||||
<!-- <Match>-->
|
||||
<!-- <!– To suppress false warnings in unit-tests for lambdas not using return values. –>-->
|
||||
<!-- <Package name="~com\.company\.service\.interfaces\.types\.contacts"/>-->
|
||||
<!-- <Bug pattern="RV_RETURN_VALUE_IGNORED"/>-->
|
||||
<!-- </Match>-->
|
||||
</FindBugsFilter>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user