issue_847: Made more styling fixes to the entity files. 300 more changes left to go.

This commit is contained in:
TheSilentCoder 2024-10-18 16:22:38 -04:00
parent 63521a4075
commit 615bbc7547
16 changed files with 567 additions and 558 deletions

View File

@ -29,54 +29,55 @@ public interface IDevIDCertificateRepository extends JpaRepository<IDevIDCertifi
*/
Page<IDevIDCertificate> findByArchiveFlag(boolean archiveFlag, Pageable pageable);
/**
* Query that retrieves a list of IDevId certificates using the provided subject.
*
* @param subject string representation of the subject
* @return a list of IDevId certificates
*/
List<IDevIDCertificate> findBySubject(String subject);
/**
* Query that retrieves a sorted list of IDevId certificates using the provided subject.
*
* @param subject string representation of the subject
* @return a sorted list of IDevId certificates
*/
List<IDevIDCertificate> findBySubjectSorted(String subject);
/**
* Query that retrieves a list of IDevId certificates using the provided subject and archive flag.
*
* @param subject string representation of the subject
* @param archiveFlag archive flag
* @return a list of IDevId certificates
*/
List<IDevIDCertificate> findBySubjectAndArchiveFlag(String subject, boolean archiveFlag);
/**
* Query that retrieves a sorted list of IDevId certificates using the provided subject and archive flag.
*
* @param subject string representation of the subject
* @param archiveFlag archive flag
* @return a sorted list of IDevId certificates
*/
List<IDevIDCertificate> findBySubjectSortedAndArchiveFlag(String subject, boolean archiveFlag);
/**
* Query that retrieves an IDevId certificate using the provided subject key identifier.
*
* @param subjectKeyIdentifier byte representation of the subject key identifier
* @return an IDevId certificate
*/
IDevIDCertificate findBySubjectKeyIdentifier(byte[] subjectKeyIdentifier);
/**
* Query that retrieves an IDevId certificate using the provided subject key and archive flag.
*
* @param subjectKeyIdString string representation of the subject key id
* @param archiveFlag archive flag
* @return an IDevId certificate
*/
IDevIDCertificate findBySubjectKeyIdStringAndArchiveFlag(String subjectKeyIdString, boolean archiveFlag);
// /**
// * Query that retrieves a list of IDevId certificates using the provided subject.
// *
// * @param subject string representation of the subject
// * @return a list of IDevId certificates
// */
// List<IDevIDCertificate> findBySubject(String subject);
//
// /**
// * Query that retrieves a sorted list of IDevId certificates using the provided subject.
// *
// * @param subject string representation of the subject
// * @return a sorted list of IDevId certificates
// */
// List<IDevIDCertificate> findBySubjectSorted(String subject);
//
// /**
// * Query that retrieves a list of IDevId certificates using the provided subject and archive flag.
// *
// * @param subject string representation of the subject
// * @param archiveFlag archive flag
// * @return a list of IDevId certificates
// */
// List<IDevIDCertificate> findBySubjectAndArchiveFlag(String subject, boolean archiveFlag);
//
// /**
// * Query that retrieves a sorted list of IDevId certificates using the provided subject and archive flag.
// *
// * @param subject string representation of the subject
// * @param archiveFlag archive flag
// * @return a sorted list of IDevId certificates
// */
// List<IDevIDCertificate> findBySubjectSortedAndArchiveFlag(String subject, boolean archiveFlag);
//
// /**
// * Query that retrieves an IDevId certificate using the provided subject key identifier.
// *
// * @param subjectKeyIdentifier byte representation of the subject key identifier
// * @return an IDevId certificate
// */
// IDevIDCertificate findBySubjectKeyIdentifier(byte[] subjectKeyIdentifier);
//
// /**
// * Query that retrieves an IDevId certificate using the provided subject key and archive flag.
// *
// * @param subjectKeyIdString string representation of the subject key id
// * @param archiveFlag archive flag
// * @return an IDevId certificate
// */
// IDevIDCertificate findBySubjectKeyIdStringAndArchiveFlag(String subjectKeyIdString, boolean archiveFlag);
}

View File

@ -28,14 +28,15 @@ import java.util.UUID;
* This class represents the Reference Integrity Manifest object that will be
* loaded into the DB and displayed in the ACA.
*/
@Getter @ToString
@Getter
@ToString
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
@Log4j2
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "ReferenceManifest")
@Access(AccessType.FIELD)
public class ReferenceManifest extends ArchivableEntity {
public class ReferenceManifest extends ArchivableEntity {
/**
* Holds the name of the 'hexDecHash' field.
@ -74,56 +75,71 @@ public class ReferenceManifest extends ArchivableEntity {
@EqualsAndHashCode.Include
@Column(columnDefinition = "mediumblob", nullable = false)
private byte[] rimBytes;
private final byte[] rimBytes;
@Setter
@EqualsAndHashCode.Include
@Column(nullable = false)
private String rimType = "Base";
@Setter
@Column
private String tagId = null;
@Setter
@Column
private boolean swidPatch = false;
@Setter
@Column
private boolean swidSupplemental = false;
@Setter
@Column
private String platformManufacturer = null;
@Setter
@Column
private String platformManufacturerId = null;
@Setter
@Column
private String swidTagVersion = null;
@Setter
@Column
private String swidVersion = null;
@Setter
@Column
private String platformModel = null;
@Setter
@Column(nullable = false)
private String fileName = null;
@Setter
@JdbcTypeCode(java.sql.Types.VARCHAR)
@Column
private UUID associatedRim;
@Setter
@Column
private String deviceName;
@Setter
@Column
private String hexDecHash = "";
@Setter
@Column
private String eventLogHash = "";
@Setter
@Column
@JsonIgnore
private String base64Hash = "";
/**
* Default constructor necessary for Hibernate.
*/
@ -141,6 +157,7 @@ public class ReferenceManifest extends ArchivableEntity {
/**
* Default constructor for ingesting the bytes of the file content.
*
* @param rimBytes - file contents.
*/
public ReferenceManifest(final byte[] rimBytes) {
@ -183,10 +200,20 @@ public class ReferenceManifest extends ArchivableEntity {
return null;
}
/**
* Determines if this reference manifest's rim type is a base rim.
*
* @return true if the rim type is a base rim, false otherwise
*/
public boolean isBase() {
return rimType.equals(BASE_RIM);
}
/**
* Determines if this reference manifest's rim type is a support rim.
*
* @return true if the rim type is a support rim, false otherwise
*/
public boolean isSupport() {
return rimType.equals(SUPPORT_RIM);
}

View File

@ -203,6 +203,7 @@ public class SupplyChainValidationSummary extends ArchivableEntity {
* Construct the criterion that can be used to query for supply chain validation summaries
* matching the configuration of this Selector.
*
* @param criteriaBuilder criteria builder
* @return a Criterion that can be used to query for supply chain validation summaries
* matching the configuration of this instance
*/

View File

@ -3,39 +3,36 @@ package hirs.attestationca.persist.entity.userdefined.certificate;
import hirs.attestationca.persist.entity.userdefined.Certificate;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.apache.commons.codec.binary.Hex;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
/**
* This class persists Certificate Authority credentials by extending the base Certificate
* class with fields unique to CA credentials.
*/
@Entity
@EqualsAndHashCode
public class CertificateAuthorityCredential extends Certificate {
@SuppressWarnings("PMD.AvoidUsingHardCodedIP")
private static final String SUBJECT_KEY_IDENTIFIER_EXTENSION = "2.5.29.14";
/**
* Holds the name of the 'subjectKeyIdentifier' field.
*/
public static final String SUBJECT_KEY_IDENTIFIER_FIELD = "subjectKeyIdentifier";
@SuppressWarnings("PMD.AvoidUsingHardCodedIP")
private static final String SUBJECT_KEY_IDENTIFIER_EXTENSION = "2.5.29.14";
private static final int CA_BYTE_SIZE = 20;
private static final int PREFIX_BYTE_SIZE = 4;
@Column
private final byte[] subjectKeyIdentifier;
@Getter
@Column
private String subjectKeyIdString;
/**
* this field is part of the TCG CA specification, but has not yet been found in
* manufacturer-provided CAs, and is therefore not currently parsed.
@ -44,6 +41,10 @@ public class CertificateAuthorityCredential extends Certificate {
@Column
private final String credentialType = "TCPA Trusted Platform Module Endorsement";
@Getter
@Column
private String subjectKeyIdString;
/**
* Construct a new CertificateAuthorityCredential given its binary contents. The given
* certificate should represent either an X509 certificate or X509 attribute certificate.
@ -117,35 +118,4 @@ public class CertificateAuthorityCredential extends Certificate {
return temp;
}
@Override
@SuppressWarnings("checkstyle:avoidinlineconditionals")
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
CertificateAuthorityCredential that = (CertificateAuthorityCredential) o;
// if (!Objects.equals(credentialType, that.credentialType)) {
// return false;
// }
return Arrays.equals(subjectKeyIdentifier, that.subjectKeyIdentifier);
}
@Override
@SuppressWarnings({"checkstyle:magicnumber", "checkstyle:avoidinlineconditionals"})
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (credentialType != null ? credentialType.hashCode() : 0);
result = 31 * result + Arrays.hashCode(subjectKeyIdentifier);
return result;
}
}

View File

@ -36,8 +36,9 @@ public class CertificateVariables {
*
*/
public static final int MAX_NUMERIC_PRECISION = 49;
/**
* Can store up to 160 bit values
* Can store up to 160 bit values.
*/
public static final int MAX_PUB_KEY_MODULUS_HEX_LENGTH = 1024;
@ -206,5 +207,8 @@ public class CertificateVariables {
*/
public static final String ECDSA_STRING = "SHA256WithECDSA";
/**
*
*/
public static final String ECDSA_SHA224_STRING = "SHA224WithECDSA";
}

View File

@ -26,50 +26,80 @@ import java.util.Objects;
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ComponentResult extends ArchivableEntity {
// String value for the Manufacturer title
/**
* String value for the Manufacturer title.
*/
public static final String ATTRIBUTE_MANUFACTURER = "Manufacturer";
// String value for the Model title
/**
* String value for the Model title.
*/
public static final String ATTRIBUTE_MODEL = "Model";
// String value for the Serial title
/**
* String value for the Serial title.
*/
public static final String ATTRIBUTE_SERIAL = "Serial";
// String value for the revision title
/**
* String value for the revision title.
*/
public static final String ATTRIBUTE_REVISION = "Revision";
// embedded component info
/**
* Embedded component info.
*/
@Setter
private String manufacturer;
@Setter
private String model;
@Setter
private String serialNumber;
@Setter
private String revisionNumber;
private boolean fieldReplaceable = false;
// this is a string because component class doesn't inherit serializable.
@Setter
private String componentClassValue;
private String componentClassStr;
private String componentClassType;
private AttributeStatus attributeStatus;
private String componentAddress;
private boolean version2 = false;
@Setter
private boolean delta = false;
@Setter
private boolean failedValidation;
private String certificateType;
private String issuerDN;
private String certificateSerialNumber;
private String boardSerialNumber;
private String uniformResourceIdentifier;
private String certificateSerialNumber;
private String boardSerialNumber;
private String uniformResourceIdentifier;
/**
* Default constructor.
* @param boardSerialNumber associated platform certificate serial number.
*
* @param boardSerialNumber associated platform certificate serial number.
* @param certificateSerialNumber unique number associated with header info.
* @param certificateType parameter holds version 1.2 or 2.0.
* @param componentIdentifier object with information from the platform certificate components.
* @param certificateType parameter holds version 1.2 or 2.0.
* @param componentIdentifier object with information from the platform certificate components.
*/
public ComponentResult(final String boardSerialNumber, final String certificateSerialNumber,
final String certificateType,
@ -94,10 +124,9 @@ public class ComponentResult extends ArchivableEntity {
// V2 fields
if (componentIdentifier.isVersion2()
&& componentIdentifier instanceof ComponentIdentifierV2) {
&& componentIdentifier instanceof ComponentIdentifierV2 ciV2) {
// this is a downside of findbugs, the code is set up to indicate if a CI is V2 or not
// but find bugs is throwing a flag because instanceof isn't being used.
ComponentIdentifierV2 ciV2 = (ComponentIdentifierV2) componentIdentifier;
this.componentClassValue = ciV2.getComponentClass().getComponentIdentifier();
this.componentClassStr = ciV2.getComponentClass().toString();
this.componentClassType = ciV2.getComponentClass().getRegistryType();
@ -117,6 +146,7 @@ public class ComponentResult extends ArchivableEntity {
* This method is only used by the certificate-details.jsp page. This
* method splits the compiled string of addresses into the component address
* object for display on the jsp page.
*
* @return a collection of component addresses.
*/
public List<ComponentAddress> getComponentAddresses() {
@ -135,6 +165,7 @@ public class ComponentResult extends ArchivableEntity {
/**
* Returns a hash code that is associated with common fields for components.
*
* @return int value of the elements
*/
public int hashCommonElements() {
@ -144,6 +175,7 @@ public class ComponentResult extends ArchivableEntity {
/**
* The string method for log entries.
*
* @return a string for the component result
*/
public String toString() {

View File

@ -53,16 +53,15 @@ import java.util.Map;
import java.util.Set;
/**
*
* This class persists an Endorsement Credential by extending the base Certificate
* class with fields unique to Endorsement credentials, as defined in the Trusted
* Computing Group Credential Profiles, specification v.1.2.
*
* <p>
* trustedcomputinggroup.org/wp-content/uploads/Credential_Profiles_V1.2_Level2_Revision8.pdf
*/
@Log4j2
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor(access= AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class EndorsementCredential extends DeviceAssociatedCertificate {
@ -105,11 +104,27 @@ public class EndorsementCredential extends DeviceAssociatedCertificate {
/**
* this field is part of the TCG EC specification, but has not yet been found in
* manufacturer-provided ECs, and is therefore not currently parsed
* manufacturer-provided ECs, and is therefore not currently parsed.
*/
@Getter
@Column
private String credentialType = "TCPA Trusted Platform Module Endorsement";
private final String credentialType = "TCPA Trusted Platform Module Endorsement";
/**
* this field is part of the TCG EC specification, but has not yet been found in
* manufacturer-provided ECs, and is therefore not currently parsed.
*/
@Getter
@Column(nullable = true)
private final String policyReference = null; // optional
/**
* this field is part of the TCG EC specification, but has not yet been found in
* manufacturer-provided ECs, and is therefore not currently parsed.
*/
@Getter
@Column(nullable = true)
private final String revocationLocator = null; // optional
@Getter
@Column
@ -131,22 +146,6 @@ public class EndorsementCredential extends DeviceAssociatedCertificate {
@Embedded
private TPMSecurityAssertions tpmSecurityAssertions = null; //optional
/*
* this field is part of the TCG EC specification, but has not yet been found in
* manufacturer-provided ECs, and is therefore not currently parsed
*/
@Getter
@Column(nullable = true)
private String policyReference = null; // optional
/*
* this field is part of the TCG EC specification, but has not yet been found in
* manufacturer-provided ECs, and is therefore not currently parsed
*/
@Getter
@Column(nullable = true)
private String revocationLocator = null; // optional
@Transient
private Set<String> expectedOids;
@ -180,6 +179,7 @@ public class EndorsementCredential extends DeviceAssociatedCertificate {
* Parses the bytes as an EK. If parsing fails initially, the optionally present header
* is removed and tried again. The cert header, if present, contains some certificate length
* information which isn't needed for parsing.
*
* @param certificateBytes the bytes of the EC
* @return the EC if a valid credential, null otherwise
*/
@ -228,6 +228,7 @@ public class EndorsementCredential extends DeviceAssociatedCertificate {
* ASN1Primitives in the certificate and searches for matching OID keys of specific values. If
* matching OID keys are found, their values are encoded in the fields of the current
* EndorsementCredential object.
*
* @throws IOException the input certificate bytes were not readable into an X509
* certificate format
*/
@ -280,9 +281,10 @@ public class EndorsementCredential extends DeviceAssociatedCertificate {
* however, the method is set to add the sequence to the OID mapping, it may search for
* patterns that correspond to the TPM Security Assertions and TPM Specification and set
* those fields appropriately.
* @param seq the sequence to parse
*
* @param seq the sequence to parse
* @param addToMapping whether or not to store the sequence value as an OID key/value value
* @param key the associated OID key with this value necessary if addToMapping is true
* @param key the associated OID key with this value necessary if addToMapping is true
* @throws IOException parsing individual subcomponents failed
*/
private void parseSequence(final ASN1Sequence seq, final boolean addToMapping,
@ -315,7 +317,7 @@ public class EndorsementCredential extends DeviceAssociatedCertificate {
ASN1Integer revision = (ASN1Integer) seq.getObjectAt(ASN1_REV_INDEX);
tpmSpecification = new TPMSpecification(family.getString(), level.getValue(),
revision.getValue());
log.debug("Found TPM Spec:" + tpmSpecification.toString());
log.debug("Found TPM Spec:" + tpmSpecification);
} else if (addToMapping && key.equals(TPM_SECURITY_ASSERTIONS)) {
// Parse TPM Security Assertions
int seqPosition = 0;
@ -341,7 +343,7 @@ public class EndorsementCredential extends DeviceAssociatedCertificate {
tpmSecurityAssertions = new TPMSecurityAssertions(ver.getValue(),
fieldUpgradeable.isTrue());
log.debug("Found TPM Assertions: " + tpmSecurityAssertions.toString());
log.debug("Found TPM Assertions: " + tpmSecurityAssertions);
// Iterate through remaining fields to set optional attributes
int tag;
ASN1TaggedObject obj;
@ -392,10 +394,11 @@ public class EndorsementCredential extends DeviceAssociatedCertificate {
* Parses the many different types of ASN1Primitives and searches for specific OID
* key/value pairs. Works by traversing the entire ASN1Primitive tree with a single
* pass and populates relevant fields in the EndorsementCredential object.
* @param component the ASN1Primitive to parse
*
* @param component the ASN1Primitive to parse
* @param addToMapping whether or not the current component has been matched as the
* value in an expected TPM OID key/value pair
* @param key if addToMapping is true, the key in the OID key/value pair
* @param key if addToMapping is true, the key in the OID key/value pair
* @throws IOException parsing of subcomponents in the tree failed.
*/
@SuppressWarnings("checkstyle:methodlength")
@ -421,13 +424,11 @@ public class EndorsementCredential extends DeviceAssociatedCertificate {
parsedFields.put(key, ((ASN1ObjectIdentifier) component).getId());
}
} else if (component instanceof ASN1TaggedObject) {
ASN1TaggedObject taggedObj = (ASN1TaggedObject) component;
} else if (component instanceof ASN1TaggedObject taggedObj) {
parseSingle(taggedObj.getBaseObject().toASN1Primitive(), addToMapping, key);
} else if (component instanceof ASN1OctetString) {
} else if (component instanceof ASN1OctetString octStr) {
// this may contain parseable data or may just be a OID key-pair value
ASN1OctetString octStr = (ASN1OctetString) component;
byte[] bytes = octStr.getOctets();
ByteArrayInputStream inStream = new ByteArrayInputStream(bytes);
ASN1InputStream octIn = new ASN1InputStream(inStream);
@ -446,12 +447,11 @@ public class EndorsementCredential extends DeviceAssociatedCertificate {
}
}
} else if (component instanceof ASN1Set) {
} else if (component instanceof ASN1Set set) {
// all ECs seen to this point use sets differently than sequences and their sets
// don't contain top level OIDs, so we can parse everything term by term, if that
// ceases to be the case, we need to switch to this parsing to be more like
// parseSequences in the future
ASN1Set set = (ASN1Set) component;
Enumeration setContents = set.getObjects();
ASN1Encodable subComp;
while (setContents.hasMoreElements()) {

View File

@ -4,6 +4,7 @@ import hirs.attestationca.persist.entity.userdefined.Certificate;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Transient;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import org.bouncycastle.asn1.ASN1Encodable;
@ -21,13 +22,13 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
@Entity
@Getter
@EqualsAndHashCode
@Log4j2
public class IDevIDCertificate extends Certificate {
@ -45,28 +46,24 @@ public class IDevIDCertificate extends Certificate {
private static final String POLICY_QUALIFIER_VERIFIED_TPM_FIXED = "2.23.133.11.1.2";
private static final String POLICY_QUALIFIER_VERIFIED_TPM_RESTRICTED = "2.23.133.11.1.3";
@Getter
@Transient
private byte[] subjectAltName;
/**
* Corresponds to the hwType field found in a Hardware Module Name (if present).
*/
@Getter
@Column
private String hwType;
/**
* Corresponds to the serial number found in a Hardware Module Name (if present).
*/
@Getter
@Column
private byte[] hwSerialNum;
/**
* TPM policy qualifiers (TCG only).
*/
@Getter
@Column
private String tpmPolicies;
@ -106,13 +103,14 @@ public class IDevIDCertificate extends Certificate {
}
/**
* Obtains TPM policy qualifiers from the Certificate Policies extension, if present. These policy qualifiers are
* specified in the TCG document "TPM 2.0 Keys for Device Identity and Attestation".
* Obtains TPM policy qualifiers from the Certificate Policies extension, if present. These policy
* qualifiers are specified in the TCG document "TPM 2.0 Keys for Device Identity and Attestation".
*
* @param policyBytes byte array representation of the policy
* @return A {@link java.util.Map} containing the policy qualifiers obtained.
* @throws IOException if policy qualifiers cannot be parsed from extension value
*/
public Map<String, Boolean> getTPMPolicyQualifiers(byte[] policyBytes) throws IOException {
public Map<String, Boolean> getTPMPolicyQualifiers(final byte[] policyBytes) throws IOException {
CertificatePolicies certPolicies =
CertificatePolicies.getInstance(JcaX509ExtensionUtils.parseExtensionValue(policyBytes));
Map<String, Boolean> policyQualifiers = new HashMap<>();
@ -167,13 +165,13 @@ public class IDevIDCertificate extends Certificate {
ASN1OctetString obj = (ASN1OctetString) input.readObject();
boolean tcgOid = false;
// Parse the otherName structure. According to the specification "TPM 2.0 Keys for Device Identity and
// Attestation", otherName can contain up to two structures: HardwareModuleName and PermanentIdentifier.
// Currently, this parser only supports HardwareModuleName (if present).
// Parse the otherName structure. According to the specification "TPM 2.0 Keys for Device Identity
// and Attestation", otherName can contain up to two structures: HardwareModuleName and
// PermanentIdentifier. Currently, this parser only supports HardwareModuleName (if present).
if (obj != null) {
// Parse Hardware Module Name structure, comprised of a hwType and hwSerialNum, and associated OID
// See also RFC 4108
// Parse Hardware Module Name structure, comprised of a hwType and hwSerialNum,
// and associated OID. See also RFC 4108
ASN1Sequence seq1 = ASN1Sequence.getInstance(obj.getOctets());
// Iterate over GeneralNames sequence until HardwareModuleName is found
@ -205,7 +203,8 @@ public class IDevIDCertificate extends Certificate {
// Some certs have been found to contain tagged objects for hwSerialNum.
// Handle this as a special case.
log.warn(
"Could not parse octet string for hwSerialNum. Attempting to parse tag.");
"Could not parse octet string for hwSerialNum. "
+ "Attempting to parse tag.");
try {
tagObj1 = ASN1TaggedObject.getInstance(seq1.getObjectAt(1));
obj2 = ASN1OctetString.getInstance(tagObj1, false);
@ -215,9 +214,9 @@ public class IDevIDCertificate extends Certificate {
}
}
// If an OID corresponding to TPM 2.0 for hwType is supported, according to the
// specification "TPM 2.0 Keys for Device Identity and Attestation", the contents of
// the hwSerialNum field will be parsed accordingly.
// If an OID corresponding to TPM 2.0 for hwType is supported, according
// to the specification "TPM 2.0 Keys for Device Identity and Attestation",
// the contents of the hwSerialNum field will be parsed accordingly.
hwType = obj1.toString();
if (hasTCGOIDs()) {
tcgOid = true;
@ -231,9 +230,9 @@ public class IDevIDCertificate extends Certificate {
}
}
// Check for certificate policy qualifiers, which should be present for IDevIDs if in compliance with the
// TCG specification.
// For interoperability reasons, this will only log a warning if a TCG OID is specified above.
// Check for certificate policy qualifiers, which should be present for IDevIDs if in compliance
// with the TCG specification. For interoperability reasons, this will only log a warning
// if a TCG OID is specified above.
byte[] policyBytes =
getX509Certificate().getExtensionValue(Extension.certificatePolicies.getId());
Map<String, Boolean> policyQualifiers = null;
@ -255,23 +254,23 @@ public class IDevIDCertificate extends Certificate {
});
tpmPolicies = qualifierSB.toString();
failCondition = !(policyQualifiers.get("verifiedTPMResidency") &&
(policyQualifiers.get("verifiedTPMFixed") ||
policyQualifiers.get("verifiedTPMRestricted")));
failCondition = !(policyQualifiers.get("verifiedTPMResidency")
&& (policyQualifiers.get("verifiedTPMFixed")
|| policyQualifiers.get("verifiedTPMRestricted")));
} else {
failCondition = true;
}
if (failCondition) {
log.warn(
"TPM policy qualifiers not found, or do not meet logical criteria. Certificate may not " +
"be in compliance with TCG specification.");
"TPM policy qualifiers not found, or do not meet logical criteria. "
+ "Certificate may not be in compliance with TCG specification.");
}
}
// Log a warning if notAfter field has an expiry date that is not indefinite
if (!this.getEndValidity().toInstant().equals(Instant.ofEpochSecond(UNDEFINED_EXPIRY_DATE))) {
log.warn("IDevID does not contain an indefinite expiry date. This may indicate an invalid " +
"certificate.");
log.warn("IDevID does not contain an indefinite expiry date. This may indicate an invalid "
+ "certificate.");
}
input.close();
@ -279,8 +278,8 @@ public class IDevIDCertificate extends Certificate {
}
/**
* Function to check whether a given IDevID certificate has TCG OIDs, in order to check compliance with various
* fields.
* Function to check whether a given IDevID certificate has TCG OIDs, in order to check compliance with
* various fields.
*
* @return a boolean value
*/
@ -291,41 +290,4 @@ public class IDevIDCertificate extends Certificate {
return false;
}
}
@Override
@SuppressWarnings("checkstyle:avoidinlineconditionals")
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
IDevIDCertificate that = (IDevIDCertificate) o;
if (!Objects.equals(getTpmPolicies(), that.getTpmPolicies())) {
return false;
}
if (!Objects.equals(getHwType(), that.getHwType())) {
return false;
}
return Arrays.equals(getHwSerialNum(), that.getHwSerialNum());
}
@Override
@SuppressWarnings({"checkstyle:magicnumber", "checkstyle:avoidinlineconditionals"})
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (getTpmPolicies() != null ? getTpmPolicies().hashCode() : 0);
result = 31 * result + (getHwType() != null ? getHwType().hashCode() : 0);
result = 31 * result + (getHwSerialNum() != null ? Arrays.hashCode(getHwSerialNum()) : 0);
return result;
}
}
}

View File

@ -28,6 +28,9 @@ public class IssuedAttestationCertificate extends DeviceAssociatedCertificate {
*/
public static final String AIC_TYPE_LABEL = "TCPA Trusted Platform Identity";
@Column
public boolean isLDevID;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "ek_id")
private EndorsementCredential endorsementCredential;
@ -36,14 +39,12 @@ public class IssuedAttestationCertificate extends DeviceAssociatedCertificate {
@JoinColumn(name = "pc_id")
private List<PlatformCredential> platformCredentials;
@Column
public boolean isLDevID;
/**
* Constructor.
* @param certificateBytes the issued certificate bytes
*
* @param certificateBytes the issued certificate bytes
* @param endorsementCredential the endorsement credential
* @param platformCredentials the platform credentials
* @param platformCredentials the platform credentials
* @throws IOException if there is a problem extracting information from the certificate
*/
public IssuedAttestationCertificate(final byte[] certificateBytes,
@ -58,9 +59,11 @@ public class IssuedAttestationCertificate extends DeviceAssociatedCertificate {
/**
* Constructor.
* @param certificatePath path to certificate
*
* @param certificatePath path to certificate
* @param endorsementCredential the endorsement credential
* @param platformCredentials the platform credentials
* @param platformCredentials the platform credentials
* @param isLDevID is it an LDev ID
* @throws IOException if there is a problem extracting information from the certificate
*/
public IssuedAttestationCertificate(final Path certificatePath,
@ -70,8 +73,4 @@ public class IssuedAttestationCertificate extends DeviceAssociatedCertificate {
throws IOException {
this(readBytes(certificatePath), endorsementCredential, platformCredentials, isLDevID);
}
public List<PlatformCredential> getPlatformCredentials() {
return new ArrayList<>(platformCredentials);
}
}

View File

@ -46,7 +46,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* This class persists Platform credentials by extending the base Certificate
@ -61,24 +60,29 @@ import java.util.UUID;
@Entity
public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* TCPA Trusted Platform Endorsement.
*/
public static final String CERTIFICATE_TYPE_1_2 = "TCPA Trusted Platform Endorsement";
/**
* TCG Trusted Platform Endorsement.
*/
public static final String CERTIFICATE_TYPE_2_0 = "TCG Trusted Platform Endorsement";
private static final int TCG_SPECIFICATION_LENGTH = 3;
// These are Object Identifiers (OIDs) for sections in the credentials
private static final String POLICY_QUALIFIER_CPSURI = "1.3.6.1.5.5.7.2.1";
private static final String POLICY_QUALIFIER_USER_NOTICE = "1.3.6.1.5.5.7.2.2";
// OID for TCG Attributes
private static final String PLATFORM_MANUFACTURER = "2.23.133.2.4";
private static final String PLATFORM_MODEL = "2.23.133.2.5";
private static final String PLATFORM_VERSION = "2.23.133.2.6";
private static final String PLATFORM_SERIAL = "2.23.133.2.23";
private static final String PLATFORM_BASEBOARD_CHASSIS_COMBINED = "2.23.133.5.1.6";
// OID for TCG Platform Class Common Attributes
private static final String PLATFORM_MANUFACTURER_2_0 = "2.23.133.5.1.1";
private static final String PLATFORM_MODEL_2_0 = "2.23.133.5.1.4";
private static final String PLATFORM_VERSION_2_0 = "2.23.133.5.1.5";
private static final String PLATFORM_SERIAL_2_0 = "2.23.133.5.1.6";
// OID for Certificate Attributes
private static final String TCG_PLATFORM_SPECIFICATION = "2.23.133.2.17";
private static final String TPM_SECURITY_ASSERTION = "2.23.133.2.18";
@ -115,16 +119,11 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
// number of extra bytes potentially present in a cert header.
private static final int PC_CERT_HEADER_BYTE_COUNT = 8;
/**
* TCPA Trusted Platform Endorsement.
*/
public static final String CERTIFICATE_TYPE_1_2 = "TCPA Trusted Platform Endorsement";
/**
* TCG Trusted Platform Endorsement.
*/
public static final String CERTIFICATE_TYPE_2_0 = "TCG Trusted Platform Endorsement";
private static final String MANUFACTURER_FIELD = "manufacturer";
private static final String MODEL_FIELD = "model";
private static final String VERSION_FIELD = "version";
private static final String PLATFORM_SERIAL_FIELD = "platformSerial";
private static final String CHASSIS_SERIAL_NUMBER_FIELD = "chassisSerialNumber";
@Column
private String credentialType = null;
@ -132,23 +131,18 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
@Column
private boolean platformBase = false;
private static final String MANUFACTURER_FIELD = "manufacturer";
@Column
private String manufacturer = null;
private static final String MODEL_FIELD = "model";
@Column
private String model = null;
private static final String VERSION_FIELD = "version";
@Column
private String version = null;
private static final String PLATFORM_SERIAL_FIELD = "platformSerial";
@Column
private String platformSerial = null;
private static final String CHASSIS_SERIAL_NUMBER_FIELD = "chassisSerialNumber";
@Column
private String chassisSerialNumber;
@ -175,6 +169,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
@Column(length = MAX_MESSAGE_LENGTH)
private String componentFailures = Strings.EMPTY;
@Column(length = MAX_MESSAGE_LENGTH)
private String componentFailureMessage = Strings.EMPTY;
@ -182,6 +177,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
private EndorsementCredential endorsementCredential = null;
private String platformChainType = Strings.EMPTY;
private boolean isDeltaChain = false;
/**
@ -190,7 +186,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
* or X509 attribute certificate.
*
* @param certificateBytes the contents of a certificate file
* @param parseFields boolean True to parse fields
* @param parseFields boolean True to parse fields
* @throws IOException if there is a problem extracting information from the certificate\
*/
public PlatformCredential(final byte[] certificateBytes,
@ -223,40 +219,11 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
this(readBytes(certificatePath), true);
}
/**
* Validate the signature on the attribute certificate in this holder.
*
* @param verifierProvider a ContentVerifierProvider that can generate a
* verifier for the signature.
* @return true if the signature is valid, false otherwise.
* @throws IOException if the signature cannot be processed or is inappropriate.
*/
public boolean isSignatureValid(final ContentVerifierProvider verifierProvider)
throws IOException {
AttributeCertificate attCert = getAttributeCertificate();
AttributeCertificateInfo acinfo = getAttributeCertificate().getAcinfo();
// Check if the algorithm identifier is the same
if (!isAlgIdEqual(acinfo.getSignature(), attCert.getSignatureAlgorithm())) {
throw new IOException("signature invalid - algorithm identifier mismatch");
}
ContentVerifier verifier;
try {
// Set ContentVerifier with the signature that will verify
verifier = verifierProvider.get((acinfo.getSignature()));
} catch (Exception e) {
throw new IOException("unable to process signature: " + e.getMessage(), e);
}
return verifier.verify(attCert.getSignatureValue().getOctets());
}
/**
* Parses the bytes as an PC. If parsing fails initially, the optionally present header
* is removed and tried again. The cert header, if present, contains some certificate length
* information which isn't needed for parsing.
*
* @param certificateBytes the bytes of the PC
* @return the PC if a valid credential, null otherwise
*/
@ -285,6 +252,103 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
return credential;
}
/**
* Verify if the AlgorithmIdentifiers are equal.
*
* @param id1 AlgorithIdentifier one
* @param id2 AlgorithIdentifier two
* @return True if are the same, False if not
*/
public static boolean isAlgIdEqual(final AlgorithmIdentifier id1,
final AlgorithmIdentifier id2) {
if (!id1.getAlgorithm().equals(id2.getAlgorithm())) {
return false;
}
if (id1.getParameters() == null) {
return id2.getParameters() == null || id2.getParameters().equals(DERNull.INSTANCE);
}
if (id2.getParameters() == null) {
return id1.getParameters() == null || id1.getParameters().equals(DERNull.INSTANCE);
}
return id1.getParameters().equals(id2.getParameters());
}
/**
* Get the PolicyQualifier from the Certificate Policies Extension.
*
* @param certificate Attribute Certificate information
* @return Policy Qualifier from the Certificate Policies Extension
*/
public static Map<String, String> getPolicyQualifier(
final AttributeCertificateInfo certificate) {
Preconditions.checkArgument(certificate.getExtensions() != null,
"Platform certificate should have extensions.");
CertificatePolicies certPolicies
= CertificatePolicies.fromExtensions(certificate.getExtensions());
Map<String, String> policyQualifiers = new HashMap<>();
String userNoticeQualifier = "";
String cpsURI = "";
if (certPolicies != null) {
// Must contain at least one Policy
for (PolicyInformation policy : certPolicies.getPolicyInformation()) {
for (ASN1Encodable pQualifierInfo : policy.getPolicyQualifiers().toArray()) {
PolicyQualifierInfo info = PolicyQualifierInfo.getInstance(pQualifierInfo);
// Subtract the data based on the OID
switch (info.getPolicyQualifierId().getId()) {
case POLICY_QUALIFIER_CPSURI:
cpsURI = DERIA5String.getInstance(info.getQualifier()).getString();
break;
case POLICY_QUALIFIER_USER_NOTICE:
UserNotice userNotice = UserNotice.getInstance(info.getQualifier());
userNoticeQualifier = userNotice.getExplicitText().getString();
break;
default:
break;
}
}
}
}
// Add to map
policyQualifiers.put("userNotice", userNoticeQualifier);
policyQualifiers.put("cpsURI", cpsURI);
return policyQualifiers;
}
/**
* Validate the signature on the attribute certificate in this holder.
*
* @param verifierProvider a ContentVerifierProvider that can generate a
* verifier for the signature.
* @return true if the signature is valid, false otherwise.
* @throws IOException if the signature cannot be processed or is inappropriate.
*/
public boolean isSignatureValid(final ContentVerifierProvider verifierProvider)
throws IOException {
AttributeCertificate attCert = getAttributeCertificate();
AttributeCertificateInfo acinfo = getAttributeCertificate().getAcinfo();
// Check if the algorithm identifier is the same
if (!isAlgIdEqual(acinfo.getSignature(), attCert.getSignatureAlgorithm())) {
throw new IOException("signature invalid - algorithm identifier mismatch");
}
ContentVerifier verifier;
try {
// Set ContentVerifier with the signature that will verify
verifier = verifierProvider.get((acinfo.getSignature()));
} catch (Exception e) {
throw new IOException("unable to process signature: " + e.getMessage(), e);
}
return verifier.verify(attCert.getSignatureValue().getOctets());
}
private void parseFields() throws IOException {
AttributeCertificateInfo certificate = getAttributeCertificate().getAcinfo();
Map<String, String> policyQualifier = getPolicyQualifier(certificate);
@ -340,6 +404,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Parse a 1.2 Platform Certificate (Attribute Certificate).
*
* @param certificate Attribute Certificate
*/
private void parseAttributeCert(final AttributeCertificateInfo certificate) {
@ -347,14 +412,14 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
= certificate.getExtensions().getExtension(Extension.subjectAlternativeName);
// It contains a Subject Alternative Name Extension
if (subjectAlternativeNameExtension != null) {
GeneralNames gnames = GeneralNames.getInstance(
GeneralNames gnames = GeneralNames.getInstance(
subjectAlternativeNameExtension.getParsedValue());
for (GeneralName gname : gnames.getNames()) {
// Check if it's a directoryName [4] Name type
if (gname.getTagNo() == GeneralName.directoryName) {
X500Name name = X500Name.getInstance(gname.getName());
for (RDN rdn: name.getRDNs()) {
for (AttributeTypeAndValue attTV: rdn.getTypesAndValues()) {
for (RDN rdn : name.getRDNs()) {
for (AttributeTypeAndValue attTV : rdn.getTypesAndValues()) {
switch (attTV.getType().toString()) {
case PLATFORM_MANUFACTURER:
this.manufacturer = attTV.getValue().toString();
@ -392,6 +457,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Parse a 2.0 Platform Certificate (Attribute Certificate).
*
* @param certificate Attribute Certificate
*/
private void parseAttributeCert2(final AttributeCertificateInfo certificate)
@ -407,8 +473,8 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
// Check if it's a directoryName [4] Name type
if (gname.getTagNo() == GeneralName.directoryName) {
X500Name name = X500Name.getInstance(gname.getName());
for (RDN rdn: name.getRDNs()) {
for (AttributeTypeAndValue attTV: rdn.getTypesAndValues()) {
for (RDN rdn : name.getRDNs()) {
for (AttributeTypeAndValue attTV : rdn.getTypesAndValues()) {
switch (attTV.getType().toString()) {
case PLATFORM_MANUFACTURER_2_0:
this.manufacturer = attTV.getValue().toString();
@ -440,6 +506,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Get the x509 Platform Certificate version.
*
* @return a big integer representing the certificate version.
*/
@Override
@ -458,6 +525,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Get the cPSuri from the Certificate Policies.
*
* @return cPSuri from the CertificatePolicies.
* @throws IOException when reading the certificate.
*/
@ -473,9 +541,10 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Get the Platform Configuration Attribute from the Platform Certificate.
*
* @return a map with all the attributes
* @throws IllegalArgumentException when there is a parsing error
* @throws IOException when reading the certificate.
* @throws IOException when reading the certificate.
*/
public Map<String, Object> getAllAttributes()
throws IllegalArgumentException, IOException {
@ -523,10 +592,11 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Get the specified attribute from the Platform Certificate.
*
* @param attributeName to retrieve from the map.
* @return an Object with the attribute.
* @throws IllegalArgumentException when there is a parsing error
* @throws IOException when reading the certificate.
* @throws IOException when reading the certificate.
*/
public Object getAttribute(final String attributeName)
throws IllegalArgumentException, IOException {
@ -535,9 +605,10 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Get the Platform Configuration Attribute from the Platform Certificate.
*
* @return a map with the Platform Configuration information.
* @throws IllegalArgumentException when there is a parsing error
* @throws IOException when reading the certificate.
* @throws IOException when reading the certificate.
*/
public PlatformConfiguration getPlatformConfiguration()
throws IllegalArgumentException, IOException {
@ -552,9 +623,10 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Get the Platform Configuration URI Attribute from the Platform Certificate.
*
* @return an URIReference object to the Platform Configuration URI.
* @throws IllegalArgumentException when there is a parsing error
* @throws IOException when reading the certificate.
* @throws IOException when reading the certificate.
*/
public URIReference getPlatformConfigurationURI()
throws IllegalArgumentException, IOException {
@ -567,9 +639,10 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Get the TBB Security Assertion from the Platform Certificate.
*
* @return a TBBSecurityAssertion object.
* @throws IllegalArgumentException when there is a parsing error
* @throws IOException when reading the certificate.
* @throws IOException when reading the certificate.
*/
public TBBSecurityAssertion getTBBSecurityAssertion()
throws IllegalArgumentException, IOException {
@ -612,6 +685,7 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
/**
* Get the list of component identifiers if there are any.
*
* @return the list of component identifiers if there are any
*/
public List<ComponentIdentifier> getComponentIdentifiers() {
@ -626,76 +700,4 @@ public class PlatformCredential extends DeviceAssociatedCertificate {
}
return Collections.emptyList();
}
/**
* Verify if the AlgorithmIdentifiers are equal.
*
* @param id1 AlgorithIdentifier one
* @param id2 AlgorithIdentifier two
* @return True if are the same, False if not
*/
public static boolean isAlgIdEqual(final AlgorithmIdentifier id1,
final AlgorithmIdentifier id2) {
if (!id1.getAlgorithm().equals(id2.getAlgorithm())) {
return false;
}
if (id1.getParameters() == null) {
if (id2.getParameters() != null && !id2.getParameters().equals(DERNull.INSTANCE)) {
return false;
}
return true;
}
if (id2.getParameters() == null) {
if (id1.getParameters() != null && !id1.getParameters().equals(DERNull.INSTANCE)) {
return false;
}
return true;
}
return id1.getParameters().equals(id2.getParameters());
}
/**
* Get the PolicyQualifier from the Certificate Policies Extension.
*
* @param certificate Attribute Certificate information
* @return Policy Qualifier from the Certificate Policies Extension
*/
public static Map<String, String> getPolicyQualifier(
final AttributeCertificateInfo certificate) {
Preconditions.checkArgument(certificate.getExtensions() != null,
"Platform certificate should have extensions.");
CertificatePolicies certPolicies
= CertificatePolicies.fromExtensions(certificate.getExtensions());
Map<String, String> policyQualifiers = new HashMap<>();
String userNoticeQualifier = "";
String cpsURI = "";
if (certPolicies != null) {
// Must contain at least one Policy
for (PolicyInformation policy : certPolicies.getPolicyInformation()) {
for (ASN1Encodable pQualifierInfo: policy.getPolicyQualifiers().toArray()) {
PolicyQualifierInfo info = PolicyQualifierInfo.getInstance(pQualifierInfo);
// Subtract the data based on the OID
switch (info.getPolicyQualifierId().getId()) {
case POLICY_QUALIFIER_CPSURI:
cpsURI = DERIA5String.getInstance(info.getQualifier()).getString();
break;
case POLICY_QUALIFIER_USER_NOTICE:
UserNotice userNotice = UserNotice.getInstance(info.getQualifier());
userNoticeQualifier = userNotice.getExplicitText().getString();
break;
default:
break;
}
}
}
}
// Add to map
policyQualifiers.put("userNotice", userNoticeQualifier);
policyQualifiers.put("cpsURI", cpsURI);
return policyQualifiers;
}
}

View File

@ -62,25 +62,16 @@ public class ComponentAddress {
/**
* Get the string value for the address type.
*
* @return the string value for the address type
*/
public String getAddressTypeValue() {
String typeValue;
switch (this.addressType.getId()) {
case ETHERNET_MAC:
typeValue = "ethernet mac";
break;
case WLAN_MAC:
typeValue = "wlan mac";
break;
case BLUETOOTH_MAC:
typeValue = "bluetooth mac";
break;
default:
typeValue = "unknown mac";
break;
}
return typeValue;
return switch (this.addressType.getId()) {
case ETHERNET_MAC -> "ethernet mac";
case WLAN_MAC -> "wlan mac";
case BLUETOOTH_MAC -> "bluetooth mac";
default -> "unknown mac";
};
}
@Override

View File

@ -6,7 +6,6 @@ import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import java.util.UUID;
@ -14,29 +13,34 @@ import java.util.UUID;
* This is tied to the ComponentResult class. If a component has a mismatched
* value from what the device has listed, this class represents which attribute
* of that component mismatched.
*
* <p>
* If this is a delta issue, the component ID would be set to null if the
* remove or modified don't exist.
*/
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ComponentAttributeResult extends ArchivableEntity {
public class ComponentAttributeResult extends ArchivableEntity {
private UUID componentId;
@Setter
private UUID provisionSessionId;
// this is used to identify Revision for the ignore policy
@Setter
private String attribute;
private String expectedValue;
private String actualValue;
/**
* Default constructor that populates the expected and actual values.
* @param componentId id associated with component result
*
* @param componentId id associated with component result
* @param expectedValue platform certificate value
* @param actualValue paccor value from the device
* @param actualValue paccor value from the device
*/
public ComponentAttributeResult(final UUID componentId,
final String expectedValue,
@ -48,10 +52,11 @@ public class ComponentAttributeResult extends ArchivableEntity {
/**
* Default constructor that populates the expected and actual values.
* @param componentId id associated with component result
*
* @param componentId id associated with component result
* @param provisionSessionId an id for the associated provision
* @param expectedValue platform certificate value
* @param actualValue paccor value from the device
* @param expectedValue platform certificate value
* @param actualValue paccor value from the device
*/
public ComponentAttributeResult(final UUID componentId,
final UUID provisionSessionId,
@ -65,6 +70,8 @@ public class ComponentAttributeResult extends ArchivableEntity {
/**
* This method is used to check the mismatched status flag for
* displaying red if there is a failure.
*
* @return true if there is status match, false otherwise
*/
public boolean checkMatchedStatus() {
return this.actualValue.equals(this.expectedValue);
@ -72,6 +79,7 @@ public class ComponentAttributeResult extends ArchivableEntity {
/**
* For the state of the object, this shouldn't be negative.
*
* @return the string value of the attribute name
*/
public String getAttribute() {

View File

@ -23,39 +23,52 @@ import java.nio.file.Path;
* componentClassRegistry ComponentClassRegistry,
* componentClassValue OCTET STRING SIZE(4) ) }
* </pre>
*
* <p>
* A note for the future.
*/
public class ComponentClass {
@Getter
public class
ComponentClass {
private static final String TCG_COMPONENT_REGISTRY = "2.23.133.18.3.1";
private static final String SMBIOS_COMPONENT_REGISTRY = "2.23.133.18.3.3";
private static final Path WINDOWS_JSON_PATH = FileSystems.getDefault().getPath(
"C:/", "ProgramData", "hirs", "aca", "default-properties", "component-class.json");
private static final Path JSON_PATH = WINDOWS_JSON_PATH.toFile().exists() ? WINDOWS_JSON_PATH :
FileSystems.getDefault().getPath(
"/etc", "hirs", "aca", "default-properties", "component-class.json");
"C:/", "ProgramData", "hirs", "aca", "default-properties", "component-class.json");
private static final Path JSON_PATH = WINDOWS_JSON_PATH.toFile().exists() ? WINDOWS_JSON_PATH
: FileSystems.getDefault().getPath(
"/etc", "hirs", "aca", "default-properties", "component-class.json");
private static final String OTHER_STRING = "Other";
private static final String UNKNOWN_STRING = "Unknown";
private static final String NONE_STRING = "None";
// Used to indicate that the component string value provided is erroneous
private static final String ERROR = "-1";
private static final int MID_INDEX = 4;
/**
* All TCG categories have Other and Unknown as the first 2 values.
*/
private static final String OTHER = "0000";
private static final String UNKNOWN = "0001";
@Getter
private String category, categoryStr;
@Getter
private String component, componentStr;
@Getter
private String registryType;
@Getter
private String componentIdentifier;
private final String registryType;
private final String componentIdentifier;
private String category;
private String categoryStr;
private String component;
private String componentStr;
/**
* Default class constructor.
@ -68,7 +81,7 @@ public class ComponentClass {
* Class Constructor that takes a String representation of the component
* value.
*
* @param registryOid the decimal notation for the type of registry
* @param registryOid the decimal notation for the type of registry
* @param componentIdentifier component value
*/
public ComponentClass(final String registryOid, final String componentIdentifier) {
@ -79,7 +92,7 @@ public class ComponentClass {
* Class Constructor that takes a String representation of the component
* value.
*
* @param componentClassPath file path for the json
* @param componentClassPath file path for the json
* @param componentIdentifier component value
*/
public ComponentClass(final Path componentClassPath, final String componentIdentifier) {
@ -91,8 +104,8 @@ public class ComponentClass {
* component value. Sets main class variables to default values and then
* matches the value against defined values in the associated JSON file.
*
* @param registryOid the decimal notation for the type of registry
* @param componentClassPath file path for the json
* @param registryOid the decimal notation for the type of registry
* @param componentClassPath file path for the json
* @param componentIdentifier component value
*/
public ComponentClass(final String registryOid,
@ -106,11 +119,11 @@ public class ComponentClass {
this.componentIdentifier = verifyComponentValue(componentIdentifier);
}
switch (registryOid) {
case TCG_COMPONENT_REGISTRY -> registryType = "TCG";
case SMBIOS_COMPONENT_REGISTRY -> registryType = "SMBIOS";
default -> registryType = UNKNOWN_STRING;
}
this.registryType = switch (registryOid) {
case TCG_COMPONENT_REGISTRY -> "TCG";
case SMBIOS_COMPONENT_REGISTRY -> "SMBIOS";
default -> UNKNOWN_STRING;
};
switch (this.componentIdentifier) {
case OTHER:
@ -135,91 +148,6 @@ public class ComponentClass {
}
}
/**
* This is the main way this class will be referenced and how it
* will be displayed on the portal.
* @return String combination of category and component.
*/
@Override
public String toString() {
String resultString;
if (componentStr.equals(UNKNOWN_STRING) || component.equals(OTHER_STRING)) {
resultString = String.format("%s%n%s", registryType, categoryStr);
} else {
resultString = String.format("%s%n%s - %s", registryType, categoryStr, componentStr);
}
return resultString;
}
/**
* Getter for the Category mapped to the associated value in.
*
* @param categories a JSON object associated with mapped categories in file
* {}@link componentIdentifier}.
*/
private void findStringValues(final JsonObject categories) {
String categoryID;
String componentMask;
boolean found = false;
if (categories != null) {
for (String name : categories.names()) {
categoryID = verifyComponentValue(categories.get(name)
.asObject().get("ID").asString());
componentMask = componentIdentifier.substring(MID_INDEX);
// check for the correct flag
if (categoryMatch(componentIdentifier.substring(0, MID_INDEX),
categoryID.substring(0, MID_INDEX))) {
found = true;
JsonObject componentTypes = categories.get(name)
.asObject().get("Types").asObject();
categoryStr = name;
switch (componentMask) {
case OTHER -> componentStr = OTHER_STRING;
case UNKNOWN -> componentStr = UNKNOWN_STRING;
default -> getComponent(componentTypes);
}
}
}
}
if (!found) {
this.categoryStr = NONE_STRING;
this.componentStr = UNKNOWN_STRING;
}
}
/**
* Returns the value of the comparison between a category and the what's in the id.
* @param category the category to compare
* @param componentId the id value to compare
* @return true if they match
*/
public boolean categoryMatch(final String category, final String componentId) {
return category.equals(componentId);
}
/**
* Getter for the component associated with the component JSON Object mapped
* in the JSON file.
*
* @param components JSON Object for the categories components
*/
private void getComponent(final JsonObject components) {
String typeID;
if (components != null) {
for (Member member : components) {
typeID = verifyComponentValue(member.getName());
if (component.equalsIgnoreCase(typeID)) {
componentStr = member.getValue().asString();
}
}
}
}
/**
* This method converts the string representation of the component ID into
* an integer. Or throws and error if the format is in error.
@ -248,4 +176,93 @@ public class ComponentClass {
return componentValue;
}
/**
* This is the main way this class will be referenced and how it
* will be displayed on the portal.
*
* @return String combination of category and component.
*/
@Override
public String toString() {
String resultString;
if (componentStr.equals(UNKNOWN_STRING) || component.equals(OTHER_STRING)) {
resultString = String.format("%s%n%s", registryType, categoryStr);
} else {
resultString = String.format("%s%n%s - %s", registryType, categoryStr, componentStr);
}
return resultString;
}
/**
* Getter for the Category mapped to the associated value in.
*
* @param categories a JSON object associated with mapped categories in file
* {}@link componentIdentifier}.
*/
private void findStringValues(final JsonObject categories) {
String categoryID;
String componentMask;
boolean found = false;
if (categories != null) {
for (String name : categories.names()) {
categoryID = verifyComponentValue(categories.get(name)
.asObject().get("ID").asString());
componentMask = componentIdentifier.substring(MID_INDEX);
// check for the correct flag
if (categoryMatch(componentIdentifier.substring(0, MID_INDEX),
categoryID.substring(0, MID_INDEX))) {
found = true;
JsonObject componentTypes = categories.get(name)
.asObject().get("Types").asObject();
this.categoryStr = name;
if (componentMask.equals(OTHER)) {
this.componentStr = OTHER_STRING;
} else if (componentMask.equals(UNKNOWN)) {
this.componentStr = UNKNOWN_STRING;
} else {
getComponent(componentTypes);
}
}
}
}
if (!found) {
this.categoryStr = NONE_STRING;
this.componentStr = UNKNOWN_STRING;
}
}
/**
* Returns the value of the comparison between a category and the what's in the id.
*
* @param category the category to compare
* @param componentId the id value to compare
* @return true if they match
*/
public boolean categoryMatch(final String category, final String componentId) {
return category.equals(componentId);
}
/**
* Getter for the component associated with the component JSON Object mapped
* in the JSON file.
*
* @param components JSON Object for the categories components
*/
private void getComponent(final JsonObject components) {
String typeID;
if (components != null) {
for (Member member : components) {
typeID = verifyComponentValue(member.getName());
if (component.equalsIgnoreCase(typeID)) {
componentStr = member.getValue().asString();
}
}
}
}
}

View File

@ -44,13 +44,11 @@ public class ComponentIdentifier {
* Maximum number of configurations.
*/
public static final int CONFIGMAX = 32;
private static final int MANDATORY_ELEMENTS = 2;
// optional sequence objects
/**
* Static variable indicated array position for the serial number.
*/
protected static final int COMPONENT_SERIAL = 0;
// optional sequence objects
/**
* Static variable indicated array position for the revision info.
*/
@ -68,13 +66,22 @@ public class ComponentIdentifier {
*/
protected static final int COMPONENT_ADDRESS = 4;
private static final int MANDATORY_ELEMENTS = 2;
private DERUTF8String componentManufacturer;
private DERUTF8String componentModel;
private DERUTF8String componentSerial;
private DERUTF8String componentRevision;
private ASN1ObjectIdentifier componentManufacturerId;
private ASN1Boolean fieldReplaceable;
private List<ComponentAddress> componentAddress;
private boolean validationResult = true;
/**
@ -93,13 +100,13 @@ public class ComponentIdentifier {
/**
* Constructor given the components values.
*
* @param componentManufacturer represents the component manufacturer
* @param componentModel represents the component model
* @param componentSerial represents the component serial number
* @param componentRevision represents the component revision
* @param componentManufacturer represents the component manufacturer
* @param componentModel represents the component model
* @param componentSerial represents the component serial number
* @param componentRevision represents the component revision
* @param componentManufacturerId represents the component manufacturer ID
* @param fieldReplaceable represents if the component is replaceable
* @param componentAddress represents a list of addresses
* @param fieldReplaceable represents if the component is replaceable
* @param componentAddress represents a list of addresses
*/
public ComponentIdentifier(final DERUTF8String componentManufacturer,
final DERUTF8String componentModel,
@ -119,6 +126,7 @@ public class ComponentIdentifier {
/**
* Constructor given the SEQUENCE that contains Component Identifier.
*
* @param sequence containing the component identifier
* @throws IllegalArgumentException if there was an error on the parsing
*/
@ -193,22 +201,6 @@ public class ComponentIdentifier {
return false;
}
/**
* Getter for the component addresses.
* @return a collection of component addresses
*/
public List<ComponentAddress> getComponentAddress() {
return componentAddress.stream().toList();
}
/**
* Setter for the list of component addresses.
* @param componentAddress collection of addresses
*/
public void setComponentAddress(List<ComponentAddress> componentAddress) {
this.componentAddress = componentAddress.stream().toList();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
@ -230,7 +222,7 @@ public class ComponentIdentifier {
}
sb.append(", fieldReplaceable=");
if (fieldReplaceable != null) {
sb.append(fieldReplaceable.toString());
sb.append(fieldReplaceable);
}
sb.append(", componentAddress=");
if (!componentAddress.isEmpty()) {

View File

@ -67,19 +67,18 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
/**
* Constructor given the components values.
*
* @param componentClass represent the component type
* @param componentManufacturer represents the component manufacturer
* @param componentModel represents the component model
* @param componentSerial represents the component serial number
* @param componentRevision represents the component revision
* @param componentClass represent the component type
* @param componentManufacturer represents the component manufacturer
* @param componentModel represents the component model
* @param componentSerial represents the component serial number
* @param componentRevision represents the component revision
* @param componentManufacturerId represents the component manufacturer ID
* @param fieldReplaceable represents if the component is replaceable
* @param componentAddress represents a list of addresses
* @param certificateIdentifier object representing certificate Id
* @param componentPlatformUri object containing the URI Reference
* @param attributeStatus object containing enumerated status
* @param fieldReplaceable represents if the component is replaceable
* @param componentAddress represents a list of addresses
* @param certificateIdentifier object representing certificate Id
* @param componentPlatformUri object containing the URI Reference
* @param attributeStatus object containing enumerated status
*/
@SuppressWarnings("checkstyle:parameternumber")
public ComponentIdentifierV2(final ComponentClass componentClass,
final DERUTF8String componentManufacturer,
final DERUTF8String componentModel,
@ -103,6 +102,7 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
/**
* Constructor given the SEQUENCE that contains Component Identifier.
*
* @param sequence containing the component identifier
* @throws IllegalArgumentException if there was an error on the parsing
*/
@ -120,7 +120,8 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
ASN1OctetString.getInstance(componentIdSeq.getObjectAt(tag)).toString());
// Mandatory values
this.setComponentManufacturer((DERUTF8String) ASN1UTF8String.getInstance(sequence.getObjectAt(tag++)));
this.setComponentManufacturer(
(DERUTF8String) ASN1UTF8String.getInstance(sequence.getObjectAt(tag++)));
this.setComponentModel((DERUTF8String) ASN1UTF8String.getInstance(sequence.getObjectAt(tag++)));
// Continue reading the sequence if it does contain more than 2 values
@ -202,9 +203,15 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
@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;
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)
@ -241,7 +248,7 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
}
sb.append(", fieldReplaceable=");
if (getFieldReplaceable() != null) {
sb.append(getFieldReplaceable().toString());
sb.append(getFieldReplaceable());
}
sb.append(", componentAddress=");
if (getComponentAddress().size() > 0) {
@ -252,11 +259,11 @@ public class ComponentIdentifierV2 extends ComponentIdentifier {
}
sb.append(", certificateIdentifier=");
if (certificateIdentifier != null) {
sb.append(certificateIdentifier.toString());
sb.append(certificateIdentifier);
}
sb.append(", componentPlatformUri=");
if (componentPlatformUri != null) {
sb.append(componentPlatformUri.toString());
sb.append(componentPlatformUri);
}
sb.append(", status=");
if (attributeStatus != null) {

View File

@ -12,13 +12,6 @@ import hirs.attestationca.persist.enums.HealthStatus;
import hirs.attestationca.portal.page.Page;
import hirs.attestationca.portal.page.PageController;
import hirs.attestationca.portal.page.PageControllerTest;
import java.io.IOException;
import java.security.Security;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@ -27,8 +20,15 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import static org.hamcrest.Matchers.hasProperty;
import java.io.IOException;
import java.security.Security;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasProperty;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
@ -40,25 +40,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class CertificateDetailsPageControllerTest extends PageControllerTest {
// Base path for the page
private String pagePath;
// Repository manager to handle data access between device entity and data storage in db
@Autowired
private DeviceRepository deviceRepository;
// Repository manager to handle data access between certificate entity and data storage in db
@Autowired
private CertificateRepository certificateRepository;
private CertificateAuthorityCredential caCertificate;
private CertificateAuthorityCredential caRootCertificate;
private PlatformCredential platformCredential;
private PlatformCredential platformCredential2;
private PlatformCredential platformCertificatePCI;
private EndorsementCredential endorsementCredential;
private IssuedAttestationCertificate issuedCredential;
// Random UUID for certificate search.
private static final String ID = "046b6c7f-0b8a-43b9-b35d-6489e6daee91";
private static final String TEST_CA_CERTIFICATE
@ -75,6 +56,21 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest {
= "/platform_credentials/basic_plat_cert_2-0.pem";
private static final String TEST_PLATFORM_CREDENTIAL_2_PCI
= "/platform_credentials/pciids_plat_cert_2-0.pem";
// Base path for the page
private final String pagePath;
// Repository manager to handle data access between device entity and data storage in db
@Autowired
private DeviceRepository deviceRepository;
// Repository manager to handle data access between certificate entity and data storage in db
@Autowired
private CertificateRepository certificateRepository;
private CertificateAuthorityCredential caCertificate;
private CertificateAuthorityCredential caRootCertificate;
private PlatformCredential platformCredential;
private PlatformCredential platformCredential2;
private PlatformCredential platformCertificatePCI;
private EndorsementCredential endorsementCredential;
private IssuedAttestationCertificate issuedCredential;
/**
* Constructor providing the Page's display and routing specification.
@ -239,7 +235,7 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest {
.getModelAndView()
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(caCertificate.getIssuer(), initialData.get("issuer"));
assertEquals(caCertificate.getIssuer(), initialData.get("issuer"));
}
@ -268,7 +264,7 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest {
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(platformCredential.getIssuer(), initialData.get("issuer"));
assertEquals(((PlatformCredential) platformCredential).getCredentialType(),
assertEquals(platformCredential.getCredentialType(),
initialData.get("credentialType"));
}
@ -298,7 +294,7 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest {
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(platformCredential2.getIssuer(), initialData.get("issuer"));
assertEquals(((PlatformCredential) platformCredential2).getCredentialType(),
assertEquals(platformCredential2.getCredentialType(),
initialData.get("credentialType"));
// Check component identifier
assertNotNull(initialData.get("componentsIdentifier"));
@ -337,7 +333,7 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest {
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(platformCertificatePCI.getIssuer(), initialData.get("issuer"));
assertEquals(((PlatformCredential) platformCertificatePCI).getCredentialType(),
assertEquals(platformCertificatePCI.getCredentialType(),
initialData.get("credentialType"));
// Check component identifier
assertNotNull(initialData.get("componentsIdentifier"));
@ -376,7 +372,7 @@ public class CertificateDetailsPageControllerTest extends PageControllerTest {
.getModel()
.get(PolicyPageController.INITIAL_DATA);
assertEquals(endorsementCredential.getIssuer(), initialData.get("issuer"));
assertEquals(((EndorsementCredential) endorsementCredential).getManufacturer(),
assertEquals(endorsementCredential.getManufacturer(),
initialData.get("manufacturer"));
}