Merge "Verify Device ID attestation data in key management test."
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
index bdb5d3b..4e878c5 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
@@ -29,6 +29,8 @@
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <!-- Needed to read the serial number during Device ID attestation tests -->
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:testOnly="true">
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
index 4050f69..bd51d86 100755
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
@@ -24,7 +24,9 @@
import android.content.Context;
import android.content.res.AssetManager;
import android.keystore.cts.Attestation;
+import android.keystore.cts.AuthorizationList;
import android.net.Uri;
+import android.os.Build;
import android.security.AttestedKeyPair;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
@@ -312,6 +314,22 @@
}
}
+ private void validateDeviceIdAttestationData(Certificate leaf,
+ String expectedSerial, String expectedImei, String expectedMeid)
+ throws CertificateParsingException {
+ Attestation attestationRecord = new Attestation((X509Certificate) leaf);
+ AuthorizationList teeAttestation = attestationRecord.getTeeEnforced();
+ assertNotNull(teeAttestation);
+ assertEquals(Build.BRAND, teeAttestation.getBrand());
+ assertEquals(Build.DEVICE, teeAttestation.getDevice());
+ assertEquals(Build.PRODUCT, teeAttestation.getProduct());
+ assertEquals(Build.MANUFACTURER, teeAttestation.getManufacturer());
+ assertEquals(Build.MODEL, teeAttestation.getModel());
+ assertEquals(expectedSerial, teeAttestation.getSerialNumber());
+ assertEquals(expectedImei, teeAttestation.getImei());
+ assertEquals(expectedMeid, teeAttestation.getMeid());
+ }
+
private void validateAttestationRecord(List<Certificate> attestation,
byte[] providedChallenge) throws CertificateParsingException {
assertNotNull(attestation);
@@ -385,6 +403,7 @@
verifySignatureOverData("SHA256withECDSA", keyPair);
List<Certificate> attestation = generated.getAttestationRecord();
validateAttestationRecord(attestation, attestationChallenge);
+ validateDeviceIdAttestationData(attestation.get(0), Build.getSerial(), null, null);
validateSignatureChain(attestation, keyPair.getPublic());
} finally {
assertTrue(mDevicePolicyManager.removeKeyPair(getWho(), alias));
diff --git a/tests/security/src/android/keystore/cts/AuthorizationList.java b/tests/security/src/android/keystore/cts/AuthorizationList.java
index d488b26..460bbf7 100644
--- a/tests/security/src/android/keystore/cts/AuthorizationList.java
+++ b/tests/security/src/android/keystore/cts/AuthorizationList.java
@@ -35,6 +35,7 @@
import com.android.org.bouncycastle.asn1.ASN1InputStream;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.security.cert.CertificateParsingException;
import java.text.DateFormat;
import java.util.Collection;
@@ -120,6 +121,14 @@
private static final int KM_TAG_OS_VERSION = KM_UINT | 705;
private static final int KM_TAG_OS_PATCHLEVEL = KM_UINT | 706;
private static final int KM_TAG_ATTESTATION_APPLICATION_ID = KM_BYTES | 709;
+ private static final int KM_TAG_ATTESTATION_ID_BRAND = KM_BYTES | 710;
+ private static final int KM_TAG_ATTESTATION_ID_DEVICE = KM_BYTES | 711;
+ private static final int KM_TAG_ATTESTATION_ID_PRODUCT = KM_BYTES | 712;
+ private static final int KM_TAG_ATTESTATION_ID_SERIAL = KM_BYTES | 713;
+ private static final int KM_TAG_ATTESTATION_ID_IMEI = KM_BYTES | 714;
+ private static final int KM_TAG_ATTESTATION_ID_MEID = KM_BYTES | 715;
+ private static final int KM_TAG_ATTESTATION_ID_MANUFACTURER = KM_BYTES | 716;
+ private static final int KM_TAG_ATTESTATION_ID_MODEL = KM_BYTES | 717;
// Map for converting padding values to strings
private static final ImmutableMap<Integer, String> paddingMap = ImmutableMap
@@ -175,6 +184,14 @@
private Integer osVersion;
private Integer osPatchLevel;
private AttestationApplicationId attestationApplicationId;
+ private String brand;
+ private String device;
+ private String serialNumber;
+ private String imei;
+ private String meid;
+ private String product;
+ private String manufacturer;
+ private String model;
public AuthorizationList(ASN1Encodable sequence) throws CertificateParsingException {
if (!(sequence instanceof ASN1Sequence)) {
@@ -260,6 +277,30 @@
attestationApplicationId = new AttestationApplicationId(Asn1Utils
.getAsn1EncodableFromBytes(Asn1Utils.getByteArrayFromAsn1(value)));
break;
+ case KM_TAG_ATTESTATION_ID_BRAND & KEYMASTER_TAG_TYPE_MASK:
+ brand = getStringFromAsn1Value(value);
+ break;
+ case KM_TAG_ATTESTATION_ID_DEVICE & KEYMASTER_TAG_TYPE_MASK:
+ device = getStringFromAsn1Value(value);
+ break;
+ case KM_TAG_ATTESTATION_ID_PRODUCT & KEYMASTER_TAG_TYPE_MASK:
+ product = getStringFromAsn1Value(value);
+ break;
+ case KM_TAG_ATTESTATION_ID_SERIAL & KEYMASTER_TAG_TYPE_MASK:
+ serialNumber = getStringFromAsn1Value(value);
+ break;
+ case KM_TAG_ATTESTATION_ID_IMEI & KEYMASTER_TAG_TYPE_MASK:
+ imei = getStringFromAsn1Value(value);
+ break;
+ case KM_TAG_ATTESTATION_ID_MEID & KEYMASTER_TAG_TYPE_MASK:
+ meid = getStringFromAsn1Value(value);
+ break;
+ case KM_TAG_ATTESTATION_ID_MANUFACTURER & KEYMASTER_TAG_TYPE_MASK:
+ manufacturer = getStringFromAsn1Value(value);
+ break;
+ case KM_TAG_ATTESTATION_ID_MODEL & KEYMASTER_TAG_TYPE_MASK:
+ model = getStringFromAsn1Value(value);
+ break;
case KM_TAG_ALL_APPLICATIONS & KEYMASTER_TAG_TYPE_MASK:
allApplications = true;
break;
@@ -492,6 +533,46 @@
return attestationApplicationId;
}
+ public String getBrand() {
+ return brand;
+ }
+
+ public String getDevice() {
+ return device;
+ }
+
+ public String getSerialNumber() {
+ return serialNumber;
+ };
+
+ public String getImei() {
+ return imei;
+ };
+
+ public String getMeid() {
+ return meid;
+ };
+
+ public String getProduct() {
+ return product;
+ };
+
+ public String getManufacturer() {
+ return manufacturer;
+ };
+
+ public String getModel() {
+ return model;
+ };
+
+ private String getStringFromAsn1Value(ASN1Primitive value) throws CertificateParsingException {
+ try {
+ return Asn1Utils.getStringFromAsn1OctetStreamAssumingUTF8(value);
+ } catch (UnsupportedEncodingException e) {
+ throw new CertificateParsingException("Error parsing ASN.1 value", e);
+ }
+ }
+
@Override
public String toString() {
StringBuilder s = new StringBuilder();
@@ -576,6 +657,13 @@
if (attestationApplicationId != null) {
s.append("\nAttestation Application Id:").append(attestationApplicationId);
}
+
+ if (brand != null) {
+ s.append("\nBrand: ").append(brand);
+ }
+ if (device != null) {
+ s.append("\nDevice type: ").append(device);
+ }
return s.toString();
}
}