Skip to content

Commit

Permalink
Override hashCode in AttestationApplicationId.
Browse files Browse the repository at this point in the history
+ some nits:
- add explicit encoding,
- reorder comparison to have the constant on RHS,
- rename private method in RootOfTrust as the previous name did not
desribe its operation,
- fix typo in an enum,
- make inner class ByteArrayComparator static.

Change-Id: Ib8999627907310492496e1b7fd08ed27d7b6b16f
  • Loading branch information
MatejZidek committed Sep 2, 2019
1 parent 9b85d77 commit 588ddd9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 19 deletions.
Expand Up @@ -19,10 +19,13 @@
import static com.google.android.attestation.Constants.ATTESTATION_APPLICATION_ID_SIGNATURE_DIGESTS_INDEX;
import static com.google.android.attestation.Constants.ATTESTATION_PACKAGE_INFO_PACKAGE_NAME_INDEX;
import static com.google.android.attestation.Constants.ATTESTATION_PACKAGE_INFO_VERSION_INDEX;
import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1OctetString;
Expand Down Expand Up @@ -111,6 +114,11 @@ public boolean equals(Object o) {
&& (compareTo((AttestationApplicationId) o) == 0);
}

@Override
public int hashCode() {
return Objects.hash(packageInfos, Arrays.deepHashCode(signatureDigests.toArray()));
}

/** Provides package's name and version number. */
public static class AttestationPackageInfo implements Comparable<AttestationPackageInfo> {
public final String packageName;
Expand All @@ -121,7 +129,8 @@ private AttestationPackageInfo(ASN1Sequence packageInfo) {
new String(
((ASN1OctetString)
packageInfo.getObjectAt(ATTESTATION_PACKAGE_INFO_PACKAGE_NAME_INDEX))
.getOctets());
.getOctets(),
UTF_8);
this.version =
((ASN1Integer) packageInfo.getObjectAt(ATTESTATION_PACKAGE_INFO_VERSION_INDEX))
.getValue()
Expand All @@ -148,11 +157,16 @@ public int compareTo(AttestationPackageInfo other) {

@Override
public boolean equals(Object o) {
return (o instanceof AttestationPackageInfo) && (0 == compareTo((AttestationPackageInfo) o));
return (o instanceof AttestationPackageInfo) && (compareTo((AttestationPackageInfo) o) == 0);
}

@Override
public int hashCode() {
return Objects.hash(packageName, version);
}
}

private class ByteArrayComparator implements java.util.Comparator<byte[]> {
private static class ByteArrayComparator implements java.util.Comparator<byte[]> {
@Override
public int compare(byte[] a, byte[] b) {
int res = Integer.compare(a.length, b.length);
Expand Down
Expand Up @@ -42,7 +42,7 @@ private RootOfTrust(ASN1Sequence rootOfTrust, int attestationVersion) {
this.deviceLocked =
ASN1Parsing.getBooleanFromAsn1(rootOfTrust.getObjectAt(ROOT_OF_TRUST_DEVICE_LOCKED_INDEX));
this.verifiedBootState =
rootOfTrustToEnum(
verifiedBootStateToEnum(
ASN1Parsing.getIntegerFromAsn1(
rootOfTrust.getObjectAt(ROOT_OF_TRUST_VERIFIED_BOOT_STATE_INDEX)));
if (attestationVersion >= 3) {
Expand All @@ -61,12 +61,12 @@ static RootOfTrust createRootOfTrust(ASN1Sequence rootOfTrust, int attestationVe
return new RootOfTrust(rootOfTrust, attestationVersion);
}

private static VerifiedBootState rootOfTrustToEnum(int securityLevel) {
private static VerifiedBootState verifiedBootStateToEnum(int securityLevel) {
switch (securityLevel) {
case KM_VERIFIED_BOOT_STATE_VERIFIED:
return VerifiedBootState.VERIFIED;
case KM_VERIFIED_BOOT_STATE_SELF_SIGNED:
return VerifiedBootState.SELFSIGNED;
return VerifiedBootState.SELF_SIGNED;
case KM_VERIFIED_BOOT_STATE_UNVERIFIED:
return VerifiedBootState.UNVERIFIED;
case KM_VERIFIED_BOOT_STATE_FAILED:
Expand All @@ -82,7 +82,7 @@ private static VerifiedBootState rootOfTrustToEnum(int securityLevel) {
*/
public enum VerifiedBootState {
VERIFIED,
SELFSIGNED,
SELF_SIGNED,
UNVERIFIED,
FAILED
}
Expand Down
Expand Up @@ -31,16 +31,17 @@
public class AttestationApplicationIdTest {

// Generated from certificate with RSA Algorithm and StrongBox Security Level
private static final String ATTESTATION_APPLICATION_ID =
"MIIBszGCAYswDAQHYW5kcm9pZAIBHTAZBBRjb20uYW5kcm9pZC5rZXljaGFpbgIBHTAZBBRjb20uYW5kcm9pZC5zZXR0"
+ "aW5ncwIBHTAZBBRjb20ucXRpLmRpYWdzZXJ2aWNlcwIBHTAaBBVjb20uYW5kcm9pZC5keW5zeXN0ZW0CAR0wHQ"
+ "QYY29tLmFuZHJvaWQuaW5wdXRkZXZpY2VzAgEdMB8EGmNvbS5hbmRyb2lkLmxvY2FsdHJhbnNwb3J0AgEdMB8E"
+ "GmNvbS5hbmRyb2lkLmxvY2F0aW9uLmZ1c2VkAgEdMB8EGmNvbS5hbmRyb2lkLnNlcnZlci50ZWxlY29tAgEdMC"
+ "AEG2NvbS5hbmRyb2lkLndhbGxwYXBlcmJhY2t1cAIBHTAhBBxjb20uZ29vZ2xlLlNTUmVzdGFydERldGVjdG9y"
+ "AgEdMCIEHWNvbS5nb29nbGUuYW5kcm9pZC5oaWRkZW5tZW51AgEBMCMEHmNvbS5hbmRyb2lkLnByb3ZpZGVycy"
+ "5zZXR0aW5ncwIBHTEiBCAwGqPLCBE0UBxF8UIqvGbCQiT9Xe1f3I8X5pcXb9hmqg==";
private static final DEROctetString ATTESTATION_APPLICATION_ID_OCTETS =
new DEROctetString(Base64.decode(ATTESTATION_APPLICATION_ID));
private static final DEROctetString ATTESTATION_APPLICATION_ID =
new DEROctetString(
Base64.decode(
"MIIBszGCAYswDAQHYW5kcm9pZAIBHTAZBBRjb20uYW5kcm9pZC5rZXljaGFpbgIBHTAZBBRjb20uYW5kcm9p"
+ "ZC5zZXR0aW5ncwIBHTAZBBRjb20ucXRpLmRpYWdzZXJ2aWNlcwIBHTAaBBVjb20uYW5kcm9pZC5keW"
+ "5zeXN0ZW0CAR0wHQQYY29tLmFuZHJvaWQuaW5wdXRkZXZpY2VzAgEdMB8EGmNvbS5hbmRyb2lkLmxv"
+ "Y2FsdHJhbnNwb3J0AgEdMB8EGmNvbS5hbmRyb2lkLmxvY2F0aW9uLmZ1c2VkAgEdMB8EGmNvbS5hbm"
+ "Ryb2lkLnNlcnZlci50ZWxlY29tAgEdMCAEG2NvbS5hbmRyb2lkLndhbGxwYXBlcmJhY2t1cAIBHTAh"
+ "BBxjb20uZ29vZ2xlLlNTUmVzdGFydERldGVjdG9yAgEdMCIEHWNvbS5nb29nbGUuYW5kcm9pZC5oaW"
+ "RkZW5tZW51AgEBMCMEHmNvbS5hbmRyb2lkLnByb3ZpZGVycy5zZXR0aW5ncwIBHTEiBCAwGqPLCBE0"
+ "UBxF8UIqvGbCQiT9Xe1f3I8X5pcXb9hmqg=="));

private static final List<AttestationPackageInfo> EXPECTED_PACKAGE_INFOS =
ImmutableList.of(
Expand All @@ -66,7 +67,7 @@ public class AttestationApplicationIdTest {
@Test
public void testCreateAttestationApplicationId() {
AttestationApplicationId attestationApplicationId =
AttestationApplicationId.createAttestationApplicationId(ATTESTATION_APPLICATION_ID_OCTETS);
AttestationApplicationId.createAttestationApplicationId(ATTESTATION_APPLICATION_ID);
assertThat(attestationApplicationId).isEqualTo(EXPECTED_ATTESTATION_APPLICATION_ID);
}

Expand All @@ -75,7 +76,31 @@ public void testCreateEmptyAttestationApplicationIdFromEmptyOrInvalidInput() {
assertThat(AttestationApplicationId.createAttestationApplicationId(null)).isNull();
assertThat(
AttestationApplicationId.createAttestationApplicationId(
new DEROctetString(Base64.decode("Invalid DEROcetet String"))))
new DEROctetString(Base64.decode("Invalid DEROctet String"))))
.isNull();
}

@Test
public void testEquals() {
AttestationApplicationId attestationApplicationId =
AttestationApplicationId.createAttestationApplicationId(ATTESTATION_APPLICATION_ID);
AttestationApplicationId emptyAttestationApplicationId =
new AttestationApplicationId(ImmutableList.of(), ImmutableList.of());

assertThat(attestationApplicationId.equals(EXPECTED_ATTESTATION_APPLICATION_ID)).isTrue();
assertThat(EXPECTED_ATTESTATION_APPLICATION_ID.equals(attestationApplicationId)).isTrue();

assertThat(attestationApplicationId.equals(emptyAttestationApplicationId)).isFalse();
assertThat(emptyAttestationApplicationId.equals(attestationApplicationId)).isFalse();
}

@Test
public void testEqualObjectsHaveEqualHashCodes() {
AttestationApplicationId attestationApplicationId =
AttestationApplicationId.createAttestationApplicationId(ATTESTATION_APPLICATION_ID);

assertThat(attestationApplicationId.equals(EXPECTED_ATTESTATION_APPLICATION_ID)).isTrue();
assertThat(attestationApplicationId.hashCode())
.isEqualTo(EXPECTED_ATTESTATION_APPLICATION_ID.hashCode());
}
}

0 comments on commit 588ddd9

Please sign in to comment.