diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java index 25ea3f5b..ccb38c09 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/AbstractAttestationCertificateAuthority.java @@ -67,11 +67,11 @@ import javax.crypto.spec.OAEPParameterSpec; import javax.crypto.spec.PSource; import javax.crypto.spec.SecretKeySpec; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyFactory; @@ -411,11 +411,8 @@ public abstract class AbstractAttestationCertificateAuthority // and later tpm20MakeCredential function RSAPublicKey ekPub = parsePublicKey(claim.getEkPublicArea().toByteArray()); AppraisalStatus.Status validationResult = AppraisalStatus.Status.FAIL; - try { - validationResult = doSupplyChainValidation(claim, ekPub); - } catch (Exception ex) { - LOG.error(ex); - } + + validationResult = doSupplyChainValidation(claim, ekPub); if (validationResult == AppraisalStatus.Status.PASS) { RSAPublicKey akPub = parsePublicKey(claim.getAkPublicArea().toByteArray()); @@ -555,19 +552,15 @@ public abstract class AbstractAttestationCertificateAuthority if (request.getQuote() != null && !request.getQuote().isEmpty()) { parseTPMQuote(request.getQuote().toStringUtf8()); TPMInfo savedInfo = device.getDeviceInfo().getTPMInfo(); - TPMInfo tpmInfo = null; - try { - tpmInfo = new TPMInfo(savedInfo.getTPMMake(), + TPMInfo tpmInfo = new TPMInfo(savedInfo.getTPMMake(), savedInfo.getTPMVersionMajor(), savedInfo.getTPMVersionMinor(), savedInfo.getTPMVersionRevMajor(), savedInfo.getTPMVersionRevMinor(), savedInfo.getPcrValues(), - this.tpmQuoteHash.getBytes("UTF-8"), - this.tpmQuoteSignature.getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - LOG.error(e); - } + this.tpmQuoteHash.getBytes(StandardCharsets.UTF_8), + this.tpmQuoteSignature.getBytes(StandardCharsets.UTF_8)); + DeviceInfoReport dvReport = new DeviceInfoReport( device.getDeviceInfo().getNetworkInfo(), device.getDeviceInfo().getOSInfo(), @@ -859,18 +852,14 @@ public abstract class AbstractAttestationCertificateAuthority // Get TPM info, currently unimplemented TPMInfo tpm; - try { - tpm = new TPMInfo(DeviceInfoReport.NOT_SPECIFIED, - (short) 0, - (short) 0, - (short) 0, - (short) 0, - this.pcrValues.getBytes("UTF-8"), - this.tpmQuoteHash.getBytes("UTF-8"), - this.tpmQuoteSignature.getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - tpm = new TPMInfo(); - } + tpm = new TPMInfo(DeviceInfoReport.NOT_SPECIFIED, + (short) 0, + (short) 0, + (short) 0, + (short) 0, + this.pcrValues.getBytes(StandardCharsets.UTF_8), + this.tpmQuoteHash.getBytes(StandardCharsets.UTF_8), + this.tpmQuoteSignature.getBytes(StandardCharsets.UTF_8)); // Create final report DeviceInfoReport dvReport = new DeviceInfoReport(nw, os, fw, hw, tpm, @@ -1272,7 +1261,13 @@ public abstract class AbstractAttestationCertificateAuthority IssuedCertificateAttributeHelper.buildSubjectAlternativeNameFromCerts( endorsementCredential, platformCredentials, deviceName); + Extension authKeyIdentifier = IssuedCertificateAttributeHelper + .buildAuthorityKeyIdentifier(endorsementCredential); + builder.addExtension(subjectAlternativeName); + if (authKeyIdentifier != null) { + builder.addExtension(authKeyIdentifier); + } // identify cert as an AIK with this extension if (IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION != null) { builder.addExtension(IssuedCertificateAttributeHelper.EXTENDED_KEY_USAGE_EXTENSION); diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/IssuedCertificateAttributeHelper.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/IssuedCertificateAttributeHelper.java index 4c98c3ad..1e1f27ea 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/IssuedCertificateAttributeHelper.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/IssuedCertificateAttributeHelper.java @@ -4,12 +4,14 @@ import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; +import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.ExtendedKeyUsage; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; @@ -19,7 +21,6 @@ import org.bouncycastle.asn1.x509.GeneralNamesBuilder; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.TBSCertificate; import org.bouncycastle.asn1.x509.AttributeCertificateInfo; -import org.springframework.util.CollectionUtils; import java.io.IOException; import java.security.cert.CertificateEncodingException; @@ -66,6 +67,28 @@ public final class IssuedCertificateAttributeHelper { // do not construct publicly } + /** + * This method builds the AKI extension that will be stored in the generated + * Attestation Issued Certificate. + * @param endorsementCredential EK object to pull AKI from. + * @return the AKI extension. + * @throws IOException on bad get instance for AKI. + */ + public static Extension buildAuthorityKeyIdentifier( + final EndorsementCredential endorsementCredential) throws IOException { + byte[] extValue = endorsementCredential.getX509Certificate() + .getExtensionValue(Extension.authorityKeyIdentifier.getId()); + + if (extValue == null) { + return null; + } + + byte[] authExtension = ASN1OctetString.getInstance(extValue).getOctets(); + AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(authExtension); + + return new Extension(Extension.authorityKeyIdentifier, true, aki.getEncoded()); + } + /** * Builds the subject alternative name based on the supplied certificates. * @param endorsementCredential the endorsement credential @@ -88,10 +111,8 @@ public final class IssuedCertificateAttributeHelper { // assemble AIK cert SAN, using info from EC and PC X500NameBuilder nameBuilder = new X500NameBuilder(); populateEndorsementCredentialAttributes(endorsementCredential, nameBuilder); - if (!CollectionUtils.isEmpty(platformCredentials)) { - for (PlatformCredential platformCredential : platformCredentials) { - populatePlatformCredentialAttributes(platformCredential, nameBuilder); - } + for (PlatformCredential platformCredential : platformCredentials) { + populatePlatformCredentialAttributes(platformCredential, nameBuilder); } // add the OID for the TCG-required TPM ID label @@ -112,7 +133,7 @@ public final class IssuedCertificateAttributeHelper { private static void populatePlatformCredentialAttributes( final PlatformCredential platformCredential, final X500NameBuilder nameBuilder) throws IOException { - if (null == platformCredential) { + if (platformCredential == null) { return; } @@ -134,7 +155,7 @@ public final class IssuedCertificateAttributeHelper { private static void populateEndorsementCredentialAttributes( final EndorsementCredential endorsementCredential, final X500NameBuilder nameBuilder) { - if (null == endorsementCredential) { + if (endorsementCredential == null) { return; } diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java index 9cc6d494..30a79d1c 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/service/SupplyChainValidationServiceImpl.java @@ -16,10 +16,12 @@ import hirs.data.persist.PCRPolicy; import hirs.data.persist.ArchivableEntity; import hirs.tpm.eventlog.TCGEventLog; import hirs.tpm.eventlog.TpmPcrEvent; +import hirs.utils.BouncyCastleUtils; import hirs.utils.ReferenceManifestValidator; import hirs.validation.SupplyChainCredentialValidator; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.bouncycastle.util.encoders.Hex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Import; import org.springframework.stereotype.Service; @@ -51,7 +53,6 @@ import hirs.data.persist.ReferenceManifest; import hirs.persist.AppraiserManager; import hirs.persist.CertificateManager; import hirs.persist.ReferenceManifestManager; -import hirs.persist.CertificateSelector; import hirs.persist.CrudManager; import hirs.persist.DBManagerException; import hirs.persist.PersistenceConfiguration; @@ -803,27 +804,49 @@ public class SupplyChainValidationServiceImpl implements SupplyChainValidationSe * certs with an identical subject and issuer org) * * @param credential the credential whose CA chain should be retrieved - * @param previouslyQueriedOrganizations a list of organizations to refrain + * @param previouslyQueriedSubjects a list of organizations to refrain * from querying * @return a Set containing all relevant CA credentials to the given * certificate's organization */ private Set getCaChainRec( final Certificate credential, - final Set previouslyQueriedOrganizations - ) { - CertificateSelector caSelector - = CertificateAuthorityCredential.select(certificateManager) - .bySubjectOrganization(credential.getIssuerOrganization()); - Set certAuthsWithMatchingOrg = caSelector.getCertificates(); + final Set previouslyQueriedSubjects) { + CertificateAuthorityCredential skiCA = null; + Set certAuthsWithMatchingIssuer = new HashSet<>(); + if (credential.getAuthKeyId() != null + && !credential.getAuthKeyId().isEmpty()) { + byte[] bytes = Hex.decode(credential.getAuthKeyId()); + skiCA = CertificateAuthorityCredential + .select(certificateManager) + .bySubjectKeyIdentifier(bytes).getCertificate(); + } - Set queriedOrganizations = new HashSet<>(previouslyQueriedOrganizations); - queriedOrganizations.add(credential.getIssuerOrganization()); + if (skiCA == null) { + if (credential.getIssuerSorted() == null + || credential.getIssuerSorted().isEmpty()) { + certAuthsWithMatchingIssuer = CertificateAuthorityCredential + .select(certificateManager) + .bySubject(credential.getIssuer()) + .getCertificates(); + } else { + //Get certificates by subject organization + certAuthsWithMatchingIssuer = CertificateAuthorityCredential + .select(certificateManager) + .bySubjectSorted(credential.getIssuerSorted()) + .getCertificates(); + } + } else { + certAuthsWithMatchingIssuer.add(skiCA); + } + Set queriedOrganizations = new HashSet<>(previouslyQueriedSubjects); + queriedOrganizations.add(credential.getIssuer()); HashSet caCreds = new HashSet<>(); - for (CertificateAuthorityCredential cred : certAuthsWithMatchingOrg) { + for (CertificateAuthorityCredential cred : certAuthsWithMatchingIssuer) { caCreds.add(cred); - if (!queriedOrganizations.contains(cred.getIssuerOrganization())) { + if (!BouncyCastleUtils.x500NameCompare(cred.getIssuer(), + cred.getSubject())) { caCreds.addAll(getCaChainRec(cred, queriedOrganizations)); } } diff --git a/HIRS_AttestationCA/src/test/java/hirs/attestationca/service/SupplyChainValidationServiceImplTest.java b/HIRS_AttestationCA/src/test/java/hirs/attestationca/service/SupplyChainValidationServiceImplTest.java index 079547de..b4d0d7b1 100644 --- a/HIRS_AttestationCA/src/test/java/hirs/attestationca/service/SupplyChainValidationServiceImplTest.java +++ b/HIRS_AttestationCA/src/test/java/hirs/attestationca/service/SupplyChainValidationServiceImplTest.java @@ -119,7 +119,7 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest // mock endorsement credential ec = mock(EndorsementCredential.class); when(ec.getEncodedPublicKey()).thenReturn(new byte[] {0x0}); - when(ec.getIssuerOrganization()).thenReturn("STMicroelectronics NV"); + when(ec.getIssuerSorted()).thenReturn("STMicroelectronics NV"); Set resultEcs = new HashSet<>(); resultEcs.add(ec); @@ -131,8 +131,8 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest when(pc.getX509Certificate()).thenReturn(cert); when(pc.getSerialNumber()).thenReturn(BigInteger.ONE); when(pc.getPlatformSerial()).thenReturn(String.valueOf(Integer.MIN_VALUE)); - when(pc.getIssuerOrganization()).thenReturn("STMicroelectronics NV"); - when(ec.getSubjectOrganization()).thenReturn("STMicroelectronics NV"); + when(pc.getIssuerSorted()).thenReturn("STMicroelectronics NV"); + when(ec.getSubjectSorted()).thenReturn("STMicroelectronics NV"); pcs = new HashSet(); pcs.add(pc); @@ -142,8 +142,8 @@ public class SupplyChainValidationServiceImplTest extends SpringPersistenceTest when(delta.getId()).thenReturn(UUID.randomUUID()); when(delta.getX509Certificate()).thenReturn(deltaCert); //when(delta.getSerialNumber()).thenReturn(BigInteger.ONE); - when(delta.getIssuerOrganization()).thenReturn("STMicroelectronics NV"); - when(delta.getSubjectOrganization()).thenReturn("STMicroelectronics NV"); + when(delta.getIssuerSorted()).thenReturn("STMicroelectronics NV"); + when(delta.getSubjectSorted()).thenReturn("STMicroelectronics NV"); Set resultPcs = new HashSet<>(); resultPcs.add(pc); diff --git a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/util/CertificateStringMapBuilder.java b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/util/CertificateStringMapBuilder.java index 60c7a734..1fe8dc0c 100644 --- a/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/util/CertificateStringMapBuilder.java +++ b/HIRS_AttestationCAPortal/src/main/java/hirs/attestationca/portal/util/CertificateStringMapBuilder.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.math.BigInteger; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Set; import java.util.List; import java.util.Comparator; @@ -21,6 +22,8 @@ import hirs.data.persist.certificate.attributes.ComponentIdentifier; import hirs.data.persist.certificate.attributes.PlatformConfiguration; import hirs.persist.CertificateManager; import hirs.utils.BouncyCastleUtils; +import org.bouncycastle.util.encoders.Hex; + import java.util.Collections; /** @@ -134,20 +137,35 @@ public final class CertificateStringMapBuilder { public static Certificate containsAllChain( final Certificate certificate, final CertificateManager certificateManager) { - - Set issuerCertificates; + Set issuerCertificates = new HashSet<>(); + CertificateAuthorityCredential skiCA = null; //Check if there is a subject organization - if (certificate.getIssuerOrganization() == null - || certificate.getIssuerOrganization().isEmpty()) { - //Get certificates by subject - issuerCertificates = CertificateAuthorityCredential.select(certificateManager) - .bySubject(certificate.getIssuer()) - .getCertificates(); + if (certificate.getAuthKeyId() != null + && !certificate.getAuthKeyId().isEmpty()) { + byte[] bytes = Hex.decode(certificate.getAuthKeyId()); + skiCA = CertificateAuthorityCredential + .select(certificateManager) + .bySubjectKeyIdentifier(bytes).getCertificate(); } else { - //Get certificates by subject organization - issuerCertificates = CertificateAuthorityCredential.select(certificateManager) - .bySubjectOrganization(certificate.getIssuerOrganization()) - .getCertificates(); + LOGGER.info(String.format("Certificate (%s) for %s has no authority key identifier.", + certificate.getClass().toString(), certificate.getSubject())); + } + + if (skiCA == null) { + if (certificate.getIssuerSorted() == null + || certificate.getIssuerSorted().isEmpty()) { + //Get certificates by subject + issuerCertificates = CertificateAuthorityCredential.select(certificateManager) + .bySubject(certificate.getIssuer()) + .getCertificates(); + } else { + //Get certificates by subject organization + issuerCertificates = CertificateAuthorityCredential.select(certificateManager) + .bySubjectSorted(certificate.getIssuerSorted()) + .getCertificates(); + } + } else { + issuerCertificates.add(skiCA); } for (Certificate issuerCert : issuerCertificates) { diff --git a/HIRS_ProvisionerTPM2/src/TPM2_Provisioner.cpp b/HIRS_ProvisionerTPM2/src/TPM2_Provisioner.cpp index 5c185742..b4853705 100644 --- a/HIRS_ProvisionerTPM2/src/TPM2_Provisioner.cpp +++ b/HIRS_ProvisionerTPM2/src/TPM2_Provisioner.cpp @@ -130,7 +130,7 @@ int provision() { RestfulClientProvisioner provisioner; string nonceBlob = provisioner.sendIdentityClaim(identityClaim); if (nonceBlob == "") { - cout << "----> Provisioning failed."; + cout << "----> Provisioning failed." << endl; cout << "Please refer to the Attestation CA for details." << endl; return 0; } diff --git a/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollector.java b/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollector.java index 48e3e7f8..21ec45dc 100644 --- a/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollector.java +++ b/HIRS_Utils/src/main/java/hirs/client/collector/DeviceInfoCollector.java @@ -32,6 +32,7 @@ import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.security.cert.CertificateException; @@ -362,7 +363,7 @@ public class DeviceInfoCollector extends AbstractCollector { if (debianRelease.exists()) { try { reader = new BufferedReader(new InputStreamReader( - new FileInputStream(debianRelease), "UTF-8")); + new FileInputStream(debianRelease), StandardCharsets.UTF_8)); while ((line = reader.readLine()) != null) { String[] ubuntuTokens = line.split("="); if (ubuntuTokens.length == 2) { @@ -394,7 +395,7 @@ public class DeviceInfoCollector extends AbstractCollector { } else if (redhatRelease.exists()) { try { reader = new BufferedReader(new InputStreamReader( - new FileInputStream(redhatRelease), "UTF-8")); + new FileInputStream(redhatRelease), StandardCharsets.UTF_8)); while ((line = reader.readLine()) != null) { String[] redhatTokens = line.split("release"); if (redhatTokens.length == 2) { @@ -543,7 +544,7 @@ public class DeviceInfoCollector extends AbstractCollector { Process quoteProcess = processBuilder.start(); quoteReader = new BufferedReader(new InputStreamReader( - quoteProcess.getInputStream(), "utf-8")); + quoteProcess.getInputStream(), StandardCharsets.UTF_8)); } catch (IOException e) { LOGGER.info("IOException occurred while attempting to read " + "tpm_version command, assume the TPM is not present and " diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/PCRPolicy.java b/HIRS_Utils/src/main/java/hirs/data/persist/PCRPolicy.java index 4f9722f6..e9ff4cc6 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/PCRPolicy.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/PCRPolicy.java @@ -12,7 +12,7 @@ import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import org.apache.logging.log4j.Logger; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -100,8 +100,7 @@ public final class PCRPolicy extends Policy { LOGGER.info("Validating quote from associated device."); boolean validated = false; short localityAtRelease = 0; - Charset charset = Charset.forName("UTF-8"); - String quoteString = new String(tpmQuote, charset); + String quoteString = new String(tpmQuote, StandardCharsets.UTF_8); TPMMeasurementRecord[] measurements = new TPMMeasurementRecord[baselinePcrs.length]; try { diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/Certificate.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/Certificate.java index d483cbec..79146587 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/Certificate.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/Certificate.java @@ -62,8 +62,10 @@ import java.security.cert.X509Certificate; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.ListIterator; import java.util.Objects; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.DistributionPoint; @@ -163,6 +165,12 @@ public abstract class Certificate extends ArchivableEntity { public static final String ISSUER_FIELD = "issuer"; @Column(nullable = false) private final String issuer; + /** + * Holds the name of the 'issuerSorted' field. + */ + public static final String ISSUER_SORTED_FIELD = "issuerSorted"; + @Column + private final String issuerSorted; /** * Holds the name of the 'subject' field. @@ -170,20 +178,12 @@ public abstract class Certificate extends ArchivableEntity { public static final String SUBJECT_FIELD = "subject"; @Column(nullable = true) private final String subject; - /** - * Holds the name of the 'issuerOrganization' field. + * Holds the name of the 'subjectSorted' field. */ - public static final String ISSUER_ORGANIZATION_FIELD = "issuerOrganization"; + public static final String SUBJECT_SORTED_FIELD = "subjectSorted"; @Column - private String issuerOrganization = null; - - /** - * Holds the name of the 'subjectOrganization' field. - */ - public static final String SUBJECT_ORGANIZATION_FIELD = "subjectOrganization"; - @Column - private String subjectOrganization = null; + private final String subjectSorted; /** * Holds the name of the 'encodedPublicKey' field. @@ -255,12 +255,15 @@ public abstract class Certificate extends ArchivableEntity { private String keyUsage; private String extendedKeyUsage; private byte[] policyConstraints; + /** + * Holds the name of the 'authorityKeyIdentifier' field. + */ + public static final String AUTHORITY_KEY_ID_FIELD = "authorityKeyIdentifier"; private String authorityKeyIdentifier; private String authorityInfoAccess; private String crlPoints; private int publicKeySize; - /** * Default constructor necessary for Hibernate. */ @@ -269,6 +272,8 @@ public abstract class Certificate extends ArchivableEntity { this.serialNumber = BigInteger.ZERO; this.issuer = null; this.subject = null; + this.issuerSorted = null; + this.subjectSorted = null; this.encodedPublicKey = null; this.publicKeyModulusHexValue = null; @@ -359,8 +364,8 @@ public abstract class Certificate extends ArchivableEntity { this.beginValidity = x509Certificate.getNotBefore(); this.endValidity = x509Certificate.getNotAfter(); this.holderSerialNumber = BigInteger.ZERO; - this.issuerOrganization = getOrganization(this.issuer); - this.subjectOrganization = getOrganization(this.subject); + this.issuerSorted = parseSortDNs(this.issuer); + this.subjectSorted = parseSortDNs(this.subject); this.policyConstraints = x509Certificate .getExtensionValue(POLICY_CONSTRAINTS); authKeyIdentifier = AuthorityKeyIdentifier @@ -395,7 +400,7 @@ public abstract class Certificate extends ArchivableEntity { // Set null values (Attribute certificates do not have this values) this.subject = null; - this.subjectOrganization = null; + this.subjectSorted = null; this.encodedPublicKey = null; this.publicKeyModulusHexValue = null; this.publicKeySize = 0; @@ -434,7 +439,7 @@ public abstract class Certificate extends ArchivableEntity { this.signature = attCert.getSignatureValue().getBytes(); this.issuer = getAttributeCertificateIssuerNames( attCertInfo.getIssuer())[0].toString(); - this.issuerOrganization = getOrganization(this.issuer); + this.issuerSorted = parseSortDNs(this.issuer); // Parse notBefore and notAfter dates this.beginValidity = recoverDate(attCertInfo @@ -536,39 +541,6 @@ public abstract class Certificate extends ArchivableEntity { return CertificateType.INVALID_CERTIFICATE; } - /** - * Extracts the organization field out of a distinguished name. Returns null if - * no organization field exists. - * @param distinguishedName distinguished name to extract the organization from - * @return the value of the organization field - */ - protected static String getOrganization(final String distinguishedName) { - String organization = null; - - // Return null for empty strings - if (distinguishedName.isEmpty()) { - return null; - } - - // Parse string to X500Name - X500Name name = new X500Name(distinguishedName); - if (name.getRDNs(RFC4519Style.o).length > 0) { - RDN rdn = name.getRDNs(RFC4519Style.o)[0]; - // For multivalue check the RDNs Attributes - if (rdn.isMultiValued()) { - for (AttributeTypeAndValue att: rdn.getTypesAndValues()) { - if (RFC4519Style.o.equals(att.getType())) { - organization = att.getValue().toString(); - } - } - } else { - organization = rdn.getFirst().getValue().toString(); - } - } - - return organization; - } - private boolean isPEM(final String possiblePEM) { return possiblePEM.contains(PEM_HEADER) || possiblePEM.contains(PEM_ATTRIBUTE_HEADER); } @@ -785,41 +757,39 @@ public abstract class Certificate extends ArchivableEntity { * @throws IOException if there is an issue deserializing either certificate */ public boolean isIssuer(final Certificate issuer) throws IOException { - CertificateType cType = issuer.getCertificateType(); - if (cType != CertificateType.X509_CERTIFICATE) { - throw new IllegalArgumentException("issuer cert must be X509Certificate"); - } - boolean isIssuer = false; - X509Certificate issuerX509 = issuer.getX509Certificate(); - - // Validate if it's the issuer - switch (getCertificateType()) { - case X509_CERTIFICATE: - X509Certificate certX509 = getX509Certificate(); - try { - certX509.verify(issuerX509.getPublicKey()); - isIssuer = true; - } catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException - | NoSuchProviderException | SignatureException e) { - LOGGER.error(e); - } - break; - - case ATTRIBUTE_CERTIFICATE: - AttributeCertificate attCert = getAttributeCertificate(); - String algorith = "SHA256withRSA"; - try { - Signature sig = Signature.getInstance(algorith); - sig.initVerify(issuerX509.getPublicKey()); - sig.update(attCert.getAcinfo().getEncoded()); - isIssuer = sig.verify(attCert.getSignatureValue().getBytes()); - } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { - LOGGER.error(e); - } - break; - default: - break; + // only run if of the correct type, otherwise false + if (issuer.getCertificateType() == CertificateType.X509_CERTIFICATE) { + X509Certificate issuerX509 = issuer.getX509Certificate(); + // Validate if it's the issuer + switch (getCertificateType()) { + case X509_CERTIFICATE: + X509Certificate certX509 = getX509Certificate(); + try { + certX509.verify(issuerX509.getPublicKey()); + isIssuer = true; + } catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException + | NoSuchProviderException | SignatureException e) { + LOGGER.error(e); + } + break; + case ATTRIBUTE_CERTIFICATE: + AttributeCertificate attCert = getAttributeCertificate(); + String algorithm = "SHA256withRSA"; + try { + Signature sig = Signature.getInstance(algorithm); + sig.initVerify(issuerX509.getPublicKey()); + sig.update(attCert.getAcinfo().getEncoded()); + isIssuer = sig.verify(attCert.getSignatureValue().getBytes()); + } catch (NoSuchAlgorithmException + | InvalidKeyException + | SignatureException e) { + LOGGER.error(e); + } + break; + default: + break; + } } return isIssuer; @@ -1055,17 +1025,17 @@ public abstract class Certificate extends ArchivableEntity { } /** - * @return this certificate's associated issuer organization + * @return this certificate's associated issuer sorted */ - public String getIssuerOrganization() { - return issuerOrganization; + public String getIssuerSorted() { + return issuerSorted; } /** - * @return this certificate's associated subject organization + * @return this certificate's associated subject sorted */ - public String getSubjectOrganization() { - return subjectOrganization; + public String getSubjectSorted() { + return subjectSorted; } /** @@ -1187,6 +1157,36 @@ public abstract class Certificate extends ArchivableEntity { } } + /** + * This method is to take the DNs from certificates and sort them in an order + * that will be used to lookup issuer certificates. This will not be stored in + * the certificate, just the DB for lookup. + * @param distinguishedName the original DN string. + * @return a modified string of sorted DNs + */ + public static String parseSortDNs(final String distinguishedName) { + StringBuilder sb = new StringBuilder(); + String dnsString; + + if (distinguishedName == null || distinguishedName.isEmpty()) { + sb.append("BLANK"); + } else { + dnsString = distinguishedName.trim(); + dnsString = dnsString.toLowerCase(); + List dnValArray = Arrays.asList(dnsString.split(",")); + Collections.sort(dnValArray); + ListIterator dnListIter = dnValArray.listIterator(); + while (dnListIter.hasNext()) { + sb.append(dnListIter.next()); + if (dnListIter.hasNext()) { + sb.append(","); + } + } + } + + return sb.toString(); + } + /** * Retrieve the X509 Name array from the issuer in an Attribute Certificate. * diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/CertificateAuthorityCredential.java b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/CertificateAuthorityCredential.java index eb4c6e53..2557ba96 100644 --- a/HIRS_Utils/src/main/java/hirs/data/persist/certificate/CertificateAuthorityCredential.java +++ b/HIRS_Utils/src/main/java/hirs/data/persist/certificate/CertificateAuthorityCredential.java @@ -2,6 +2,7 @@ package hirs.data.persist.certificate; import hirs.persist.CertificateManager; import hirs.persist.CertificateSelector; +import org.apache.commons.codec.binary.Hex; import javax.persistence.Column; import javax.persistence.Entity; @@ -15,7 +16,8 @@ import java.util.Arrays; */ @Entity public class CertificateAuthorityCredential extends Certificate { - @SuppressWarnings("PMD.AvoidUsingHardCodedIP") // this is not an IP address; PMD thinks it is + + @SuppressWarnings("PMD.AvoidUsingHardCodedIP") private static final String SUBJECT_KEY_IDENTIFIER_EXTENSION = "2.5.29.14"; /** @@ -26,9 +28,12 @@ public class CertificateAuthorityCredential extends Certificate { @Column private final byte[] subjectKeyIdentifier; - /* + @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 + * manufacturer-provided CAs, and is therefore not currently parsed. */ @Column private String credentialType = "TCPA Trusted Platform Module Endorsement"; @@ -82,6 +87,9 @@ public class CertificateAuthorityCredential extends Certificate { super(certificateBytes); this.subjectKeyIdentifier = getX509Certificate().getExtensionValue(SUBJECT_KEY_IDENTIFIER_EXTENSION); + if (this.subjectKeyIdentifier != null) { + this.subjectKeyIdString = Hex.encodeHexString(this.subjectKeyIdentifier); + } } /** @@ -119,12 +127,20 @@ public class CertificateAuthorityCredential extends Certificate { * @return this certificate's subject key identifier. */ public byte[] getSubjectKeyIdentifier() { - if (null != subjectKeyIdentifier) { + if (subjectKeyIdentifier != null) { return subjectKeyIdentifier.clone(); } return null; } + /** + * Getter for the string rep of the ID. + * @return a string + */ + public String getSubjectKeyIdString() { + return this.subjectKeyIdString; + } + @Override @SuppressWarnings("checkstyle:avoidinlineconditionals") public boolean equals(final Object o) { diff --git a/HIRS_Utils/src/main/java/hirs/persist/CertificateSelector.java b/HIRS_Utils/src/main/java/hirs/persist/CertificateSelector.java index 0527ef0a..c3c81f01 100644 --- a/HIRS_Utils/src/main/java/hirs/persist/CertificateSelector.java +++ b/HIRS_Utils/src/main/java/hirs/persist/CertificateSelector.java @@ -175,7 +175,8 @@ public abstract class CertificateSelector { public CertificateSelector byIssuer(final String issuer) { Preconditions.checkArgument( StringUtils.isNotEmpty(issuer), - "issuer cannot be null or empty." + String.format("%s: issuer cannot be null or empty.", + this.certificateClass.toString()) ); setFieldValue(Certificate.ISSUER_FIELD, issuer); @@ -192,7 +193,8 @@ public abstract class CertificateSelector { public CertificateSelector bySubject(final String subject) { Preconditions.checkArgument( StringUtils.isNotEmpty(subject), - "subject cannot be null or empty." + String.format("%s: subject cannot be null or empty.", + this.certificateClass.toString()) ); setFieldValue(Certificate.SUBJECT_FIELD, subject); @@ -200,36 +202,38 @@ public abstract class CertificateSelector { } /** - * Specify an issuer organization string that certificates must have to be considered + * Specify the sorted issuer string that certificates must have to be considered * as matching. * - * @param organization certificate issuer organization string to query, not empty or null + * @param issuerSorted certificate issuer organization string to query, not empty or null * @return this instance (for chaining further calls) */ - public CertificateSelector byIssuerOrganization(final String organization) { + public CertificateSelector byIssuerSorted(final String issuerSorted) { Preconditions.checkArgument( - StringUtils.isNotEmpty(organization), - "organization cannot be null or empty." + StringUtils.isNotEmpty(issuerSorted), + String.format("%s: issuerSorted cannot be null or empty.", + this.certificateClass.toString()) ); - setFieldValue(Certificate.ISSUER_ORGANIZATION_FIELD, organization); + setFieldValue(Certificate.ISSUER_SORTED_FIELD, issuerSorted); return this; } /** - * Specify a subject organization string that certificates must have to be considered + * Specify the sorted subject string that certificates must have to be considered * as matching. * - * @param organization certificate subject organization string to query, not empty or null + * @param subjectSorted certificate subject organization string to query, not empty or null * @return this instance (for chaining further calls) */ - public CertificateSelector bySubjectOrganization(final String organization) { + public CertificateSelector bySubjectSorted(final String subjectSorted) { Preconditions.checkArgument( - StringUtils.isNotEmpty(organization), - "organization cannot be null or empty." + StringUtils.isNotEmpty(subjectSorted), + String.format("%s: subjectSorted cannot be null or empty.", + this.certificateClass.toString()) ); - setFieldValue(Certificate.SUBJECT_ORGANIZATION_FIELD, organization); + setFieldValue(Certificate.SUBJECT_SORTED_FIELD, subjectSorted); return this; } @@ -243,7 +247,8 @@ public abstract class CertificateSelector { public CertificateSelector byEncodedPublicKey(final byte[] encodedPublicKey) { Preconditions.checkArgument( ArrayUtils.isNotEmpty(encodedPublicKey), - "publicKey cannot be null or empty." + String.format("%s: publicKey cannot be null or empty.", + this.certificateClass.toString()) ); setFieldValue( @@ -254,6 +259,23 @@ public abstract class CertificateSelector { return this; } + /** + * Specify the authority key identifier to find certificate(s). + * @param authorityKeyIdentifier the string of the AKI associated with the certificate. + * @return this instance + */ + public CertificateSelector byAuthorityKeyIdentifier(final String authorityKeyIdentifier) { + Preconditions.checkArgument( + StringUtils.isNotEmpty(authorityKeyIdentifier), + String.format("%s: authorityKeyIdentifier cannot be null or empty.", + this.certificateClass.toString()) + ); + + setFieldValue(Certificate.AUTHORITY_KEY_ID_FIELD, authorityKeyIdentifier); + + return this; + } + /** * Specify a public key modulus that certificates must have to be considered * as matching. @@ -264,7 +286,8 @@ public abstract class CertificateSelector { public CertificateSelector byPublicKeyModulus(final BigInteger publicKeyModulus) { Preconditions.checkArgument( publicKeyModulus != null, - "Public key modulus cannot be null" + String.format("%s: Public key modulus cannot be null", + this.certificateClass.toString()) ); setFieldValue( @@ -428,8 +451,7 @@ public abstract class CertificateSelector { // construct and execute query private Set execute() { - Set results = certificateManager.get(this); - return results; + return certificateManager.get(this); } /** diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java index e7dc7199..92975056 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/TCGEventLog.java @@ -2,8 +2,8 @@ package hirs.tpm.eventlog; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; @@ -350,9 +350,8 @@ public final class TCGEventLog { * * @param log The Event Log * @return true if EfiSpecIDEvent is found and indicates that the format is crypto agile - * @throws UnsupportedEncodingException if parsing error occurs. */ - private boolean isLogCrytoAgile(final byte[] log) throws UnsupportedEncodingException { + private boolean isLogCrytoAgile(final byte[] log) { byte[] eType = new byte[UefiConstants.SIZE_4]; System.arraycopy(log, UefiConstants.SIZE_4, eType, 0, UefiConstants.SIZE_4); byte[] eventType = HexUtils.leReverseByte(eType); @@ -361,8 +360,10 @@ public final class TCGEventLog { return false; } // Event Type should be EV_NO_ACTION byte[] signature = new byte[SIG_SIZE]; - System.arraycopy(log, SIG_OFFSET, signature, 0, SIG_SIZE); // should be "Spec ID Event03" - String sig = new String(signature, "UTF-8").substring(0, SIG_SIZE - 1); // remove null char + // should be "Spec ID Event03" + System.arraycopy(log, SIG_OFFSET, signature, 0, SIG_SIZE); + // remove null char + String sig = new String(signature, StandardCharsets.UTF_8).substring(0, SIG_SIZE - 1); return sig.equals("Spec ID Event03"); } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvCompactHash.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvCompactHash.java index 1a2df0e2..0a94e997 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvCompactHash.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvCompactHash.java @@ -1,6 +1,7 @@ package hirs.tpm.eventlog.events; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import hirs.tpm.eventlog.uefi.UefiConstants; import hirs.utils.HexUtils; @@ -38,7 +39,7 @@ public class EvCompactHash { if (event.length == UefiConstants.SIZE_4) { // older PFP defines as 4 byte ESI pointer. eventInfo = " ESI = " + HexUtils.byteArrayToHexString(event); } else { // otherwise assume the event content is a string - eventInfo = " " + new String(event, "UTF-8"); + eventInfo = " " + new String(event, StandardCharsets.UTF_8); } return eventInfo; } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiSpecIdEvent.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiSpecIdEvent.java index 5e0f5682..332d2e28 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiSpecIdEvent.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvEfiSpecIdEvent.java @@ -1,6 +1,6 @@ package hirs.tpm.eventlog.events; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import hirs.tpm.eventlog.TcgTpmtHa; @@ -67,13 +67,13 @@ public class EvEfiSpecIdEvent { /** * EvEfiSpecIdEvent Constructor. * @param efiSpecId byte array holding the spec ID Event. - * @throws UnsupportedEncodingException if input fails to parse. */ - public EvEfiSpecIdEvent(final byte[] efiSpecId) throws UnsupportedEncodingException { + public EvEfiSpecIdEvent(final byte[] efiSpecId) { byte[] signatureBytes = new byte[UefiConstants.SIZE_16]; System.arraycopy(efiSpecId, 0, signatureBytes, 0, UefiConstants.SIZE_16); signature = HexUtils.byteArrayToHexString(signatureBytes); - signature = new String(signatureBytes, "UTF-8").substring(0, UefiConstants.SIZE_15); + signature = new String(signatureBytes, StandardCharsets.UTF_8) + .substring(0, UefiConstants.SIZE_15); byte[] platformClassBytes = new byte[UefiConstants.SIZE_4]; System.arraycopy(efiSpecId, UefiConstants.OFFSET_16, platformClassBytes, 0, @@ -167,12 +167,12 @@ public class EvEfiSpecIdEvent { */ public String toString() { String specInfo = ""; - if (signature == "Spec ID Event#") { + if (signature.equals("Spec ID Event#")) { specInfo += "Platform Profile Specification version = " + vMaj + "." + vMin + " using errata version" + errata; } else { specInfo = "EV_NO_ACTION event named " + signature - + " ecncountered but support for processing it has not been added to this application"; + + " encountered but support for processing it has not been added to this application"; } return specInfo; } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvSCrtmVersion.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvSCrtmVersion.java index f0364aeb..8d3ee569 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvSCrtmVersion.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/events/EvSCrtmVersion.java @@ -1,6 +1,7 @@ package hirs.tpm.eventlog.events; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import hirs.tpm.eventlog.uefi.UefiConstants; import hirs.tpm.eventlog.uefi.UefiGuid; @@ -25,10 +26,9 @@ public class EvSCrtmVersion { /** * Checks if event data is null and if not it converts to a String. * @param data byte array holding the vent content. - * @throws UnsupportedEncodingException if parsing issues exist. * @return String representation of the version. */ - public String sCrtmVersion(final byte[] data) throws UnsupportedEncodingException { + public String sCrtmVersion(final byte[] data) { UefiGuid guid = null; if (data == null) { description = "invalid content event data"; @@ -42,7 +42,7 @@ public class EvSCrtmVersion { } else if (data.length < UefiConstants.SIZE_4) { description = HexUtils.byteArrayToHexString(data); } else if (EvPostCode.isAscii(data)) { - description = new String(data, "UTF-8"); + description = new String(data, StandardCharsets.UTF_8); } else { description = "Unknown Version format"; } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiDevicePath.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiDevicePath.java index cc0db02a..8fa223c1 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiDevicePath.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiDevicePath.java @@ -1,6 +1,7 @@ package hirs.tpm.eventlog.uefi; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import hirs.utils.HexUtils; @@ -276,10 +277,8 @@ private String hardDriveSubType(final byte[] path, final int offset) { * @param path * @param offset * @return file path info. - * @throws UnsupportedEncodingException */ -private String filePathSubType(final byte[] path, final int offset) - throws UnsupportedEncodingException { +private String filePathSubType(final byte[] path, final int offset) { subType = "File Path = "; byte[] lengthBytes = new byte[UefiConstants.SIZE_2]; System.arraycopy(path, 2 + offset, lengthBytes, 0, UefiConstants.SIZE_2); @@ -287,7 +286,7 @@ private String filePathSubType(final byte[] path, final int offset) byte[] filePath = new byte[subTypeLength]; System.arraycopy(path, UefiConstants.OFFSET_4 + offset, filePath, 0, subTypeLength); byte[] fileName = convertChar16tobyteArray(filePath); - subType += new String(fileName, "UTF-8"); + subType += new String(fileName, StandardCharsets.UTF_8); return subType; } diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiPartition.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiPartition.java index 24af2bec..d0ade073 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiPartition.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiPartition.java @@ -1,6 +1,6 @@ package hirs.tpm.eventlog.uefi; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import hirs.utils.HexUtils; /** @@ -39,9 +39,8 @@ public class UefiPartition { /** * Processes a UEFI defined partition entry. * @param table byte array holding the partition table. - * @throws UnsupportedEncodingException if parsing of the data fails. */ - public UefiPartition(final byte[] table) throws UnsupportedEncodingException { + public UefiPartition(final byte[] table) { byte[] partitionGuidBytes = new byte[UefiConstants.SIZE_16]; System.arraycopy(table, 0, partitionGuidBytes, 0, UefiConstants.SIZE_16); partitionTypeGUID = new UefiGuid(partitionGuidBytes); @@ -56,7 +55,7 @@ public class UefiPartition { System.arraycopy(table, UefiConstants.PART_NAME_LENGTH, partitionNameBytes, 0, UefiConstants.UEFI_PT_LENGTH); byte[] pName = convertChar16tobyteArray(partitionNameBytes); - partitionName = new String(pName, "UTF-8").trim(); + partitionName = new String(pName, StandardCharsets.UTF_8).trim(); } /** diff --git a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiVariable.java b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiVariable.java index 4763328f..096e6655 100644 --- a/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiVariable.java +++ b/HIRS_Utils/src/main/java/hirs/tpm/eventlog/uefi/UefiVariable.java @@ -3,6 +3,7 @@ package hirs.tpm.eventlog.uefi; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.util.ArrayList; @@ -24,7 +25,7 @@ public class UefiVariable { /** UEFI defined variable identifier GUID. */ private UefiGuid uefiGuid = null; /** List of Signature lists. */ - private ArrayList certSuperList = new ArrayList(); + private ArrayList certSuperList = new ArrayList<>(); /** Name of the UEFI variable. */ private String varName = ""; /** UEFI defined Boot Variable. */ @@ -70,15 +71,15 @@ public UefiVariable(final byte[] variableData) uefiVaribelData = new byte[variableLength]; System.arraycopy(variableData, UefiConstants.OFFSET_32 + nlength * UefiConstants.SIZE_2, uefiVaribelData, 0, variableLength); - varName = new String(name, "UTF-8"); + varName = new String(name, StandardCharsets.UTF_8); String tmpName = varName; if (varName.contains("Boot00")) { tmpName = "Boot00"; } switch (tmpName) { - case "PK": processSigList(uefiVaribelData); break; - case "KEK": processSigList(uefiVaribelData); break; - case "db": processSigList(uefiVaribelData); break; + case "PK": + case "KEK": + case "db": case "dbx": processSigList(uefiVaribelData); break; case "Boot00": bootv = new UefiBootVariable(uefiVaribelData); break; case "BootOrder": booto = new UefiBootOrder(uefiVaribelData); break; @@ -147,14 +148,15 @@ public String toString() { tmpName = varName; } switch (tmpName) { - case "Shim": efiVariable.append(printCert(uefiVaribelData, 0)); break; + case "Shim": case "MokList": efiVariable.append(printCert(uefiVaribelData, 0)); break; case "Boot00": efiVariable.append(bootv.toString()); break; case "BootOrder": efiVariable.append(booto.toString()); break; case "SecureBoot": efiVariable.append(sb.toString()); break; default: if (!tmpName.isEmpty()) { - efiVariable.append("Data not provided for UEFI variable named " + tmpName + " "); + efiVariable.append(String.format("Data not provided for UEFI variable named %s ", + tmpName)); } else { efiVariable.append("Data not provided "); } diff --git a/HIRS_Utils/src/main/java/hirs/utils/exec/AsynchronousExecResult.java b/HIRS_Utils/src/main/java/hirs/utils/exec/AsynchronousExecResult.java index 6675d8a6..02f0d891 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/exec/AsynchronousExecResult.java +++ b/HIRS_Utils/src/main/java/hirs/utils/exec/AsynchronousExecResult.java @@ -5,6 +5,7 @@ import org.apache.commons.exec.DefaultExecuteResultHandler; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; /** * An implementation of ExecResult that facilitates working with @@ -84,7 +85,7 @@ public class AsynchronousExecResult implements ExecResult { checkFinished(); if (stdOut != null) { - return ((ByteArrayOutputStream) stdOut).toString("UTF-8"); + return ((ByteArrayOutputStream) stdOut).toString(StandardCharsets.UTF_8.toString()); } else { return null; } diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/certificate/CertificateTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/certificate/CertificateTest.java index f0fe3a1e..ee8f0bbd 100644 --- a/HIRS_Utils/src/test/java/hirs/data/persist/certificate/CertificateTest.java +++ b/HIRS_Utils/src/test/java/hirs/data/persist/certificate/CertificateTest.java @@ -481,28 +481,6 @@ public class CertificateTest { ); } - /** - * Tests that Certificate's getOrganization method can properly parse an organization - * from a comma separated RDN. - * @throws IOException unable to parse organization - */ - @Test - public void testGetSingleOrganization() throws IOException { - String parsedOrg = Certificate.getOrganization(RDN_COMMA_SEPARATED); - Assert.assertEquals(RDN_COMMA_SEPARATED_ORGANIZATION, parsedOrg); - } - - /** - * Tests that Certificate's getOrganization method can properly parse an organization - * from a multivalue RDN. - * @throws IOException unable to parse organization - */ - @Test - public void testGetMultiRdnOrganization() throws IOException { - String parsedOrg = Certificate.getOrganization(RDN_MULTIVALUE); - Assert.assertEquals(RDN_MULTIVALUE_ORGANIZATION, parsedOrg); - } - /** * Construct a CertificateAuthorityCredential from the given parameters. * diff --git a/HIRS_Utils/src/test/java/hirs/persist/CertificateSelectorTest.java b/HIRS_Utils/src/test/java/hirs/persist/CertificateSelectorTest.java index cfca83c8..f5a8c496 100644 --- a/HIRS_Utils/src/test/java/hirs/persist/CertificateSelectorTest.java +++ b/HIRS_Utils/src/test/java/hirs/persist/CertificateSelectorTest.java @@ -100,7 +100,7 @@ public class CertificateSelectorTest extends SpringPersistenceTest { */ @Test(expectedExceptions = IllegalArgumentException.class) public void testNullByIssuerOrganization() { - CertificateAuthorityCredential.select(certMan).byIssuerOrganization(null); + CertificateAuthorityCredential.select(certMan).byIssuerSorted(null); } /** @@ -108,6 +108,6 @@ public class CertificateSelectorTest extends SpringPersistenceTest { */ @Test(expectedExceptions = IllegalArgumentException.class) public void testNullBySubjectOrganization() { - CertificateAuthorityCredential.select(certMan).bySubjectOrganization(null); + CertificateAuthorityCredential.select(certMan).bySubjectSorted(null); } } diff --git a/HIRS_Utils/src/test/java/hirs/persist/DBCertificateManagerTest.java b/HIRS_Utils/src/test/java/hirs/persist/DBCertificateManagerTest.java index 60e67612..9695b8fe 100644 --- a/HIRS_Utils/src/test/java/hirs/persist/DBCertificateManagerTest.java +++ b/HIRS_Utils/src/test/java/hirs/persist/DBCertificateManagerTest.java @@ -344,7 +344,7 @@ public class DBCertificateManagerTest extends SpringPersistenceTest { Set retrievedCerts = CertificateAuthorityCredential.select(certMan) - .bySubjectOrganization(stmEkCert.getIssuerOrganization()) + .bySubjectSorted(stmEkCert.getIssuerSorted()) .getCertificates(); Assert.assertEquals( @@ -355,7 +355,7 @@ public class DBCertificateManagerTest extends SpringPersistenceTest { Set secondRetrievedCerts = CertificateAuthorityCredential.select(certMan) - .bySubjectOrganization(stmRootCaCert.getIssuerOrganization()) + .bySubjectSorted(stmRootCaCert.getIssuerSorted()) .getCertificates(); Assert.assertEquals( @@ -380,7 +380,7 @@ public class DBCertificateManagerTest extends SpringPersistenceTest { Set retrievedCerts = CertificateAuthorityCredential.select(certMan) - .byIssuerOrganization(stmRootCaCert.getIssuerOrganization()) + .byIssuerSorted(stmRootCaCert.getIssuerSorted()) .getCertificates(); Assert.assertEquals( @@ -706,7 +706,7 @@ public class DBCertificateManagerTest extends SpringPersistenceTest { /** * Tests that a {@link CertificateSelector} can be used to retrieve certificates in various - * forms, including {@link Certificate}, {@link X509Certificate}, and {@link KeyStore}. + * forms, including {@link Certificate}. * * @throws IOException if there is a problem creating the certificate * @throws KeyStoreException if there is a problem constructing the resultant KeyStore