From 114397015f46a8000ca54696dd26fd1ba2d36054 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 15 Apr 2023 14:18:39 -0400 Subject: [PATCH] raise minimum OS version to Android 10 Android 11 is the oldest version receiving official security support but the Android 10 end-of-life was relatively recent. --- app/build.gradle.kts | 2 +- .../auditor/AttestationProtocol.java | 9 ++----- .../attestation/auditor/RemoteVerifyJob.java | 17 +++++------- .../attestation/auditor/SubmitSampleJob.java | 26 ++++++++----------- app/src/main/res/values/strings.xml | 2 +- 5 files changed, 21 insertions(+), 35 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a70cf80e5..3c3e28ecc 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -45,7 +45,7 @@ android { defaultConfig { applicationId = "app.attestation.auditor" - minSdk = 26 + minSdk = 29 targetSdk = 33 versionCode = 69 versionName = versionCode.toString() diff --git a/app/src/main/java/app/attestation/auditor/AttestationProtocol.java b/app/src/main/java/app/attestation/auditor/AttestationProtocol.java index b584905f1..152fe7856 100644 --- a/app/src/main/java/app/attestation/auditor/AttestationProtocol.java +++ b/app/src/main/java/app/attestation/auditor/AttestationProtocol.java @@ -243,7 +243,7 @@ class AttestationProtocol { private static final byte AUDITOR_APP_VARIANT_PLAY = 1; private static final byte AUDITOR_APP_VARIANT_DEBUG = 2; private static final int AUDITOR_APP_MINIMUM_VERSION = 47; - private static final int OS_VERSION_MINIMUM = 80000; + private static final int OS_VERSION_MINIMUM = 100000; private static final int OS_PATCH_LEVEL_MINIMUM = 201801; private static final int VENDOR_PATCH_LEVEL_MINIMUM = 201808; private static final int BOOT_PATCH_LEVEL_MINIMUM = 201809; @@ -1362,11 +1362,6 @@ static class AttestationResult { } } - @TargetApi(28) - static void enableStrongBox(final KeyGenParameterSpec.Builder builder) { - builder.setIsStrongBoxBacked(true); - } - @TargetApi(31) static void setAttestKeyAlias(final KeyGenParameterSpec.Builder builder, final String alias) { builder.setAttestKeyAlias(alias); @@ -1384,7 +1379,7 @@ static KeyGenParameterSpec.Builder getKeyBuilder(final String alias, final int p builder.setKeyValidityEnd(new Date(startTime.getTime() + EXPIRE_OFFSET_MS)); } if (useStrongBox) { - enableStrongBox(builder); + builder.setIsStrongBoxBacked(true); } return builder; } diff --git a/app/src/main/java/app/attestation/auditor/RemoteVerifyJob.java b/app/src/main/java/app/attestation/auditor/RemoteVerifyJob.java index 786160225..8de8b8442 100644 --- a/app/src/main/java/app/attestation/auditor/RemoteVerifyJob.java +++ b/app/src/main/java/app/attestation/auditor/RemoteVerifyJob.java @@ -88,9 +88,8 @@ static void schedule(final Context context, int interval) { final long intervalMillis = interval * 1000; final long flexMillis = intervalMillis / 10; if (jobInfo != null && - (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && - jobInfo.getEstimatedNetworkDownloadBytes() == ESTIMATED_DOWNLOAD_BYTES && - jobInfo.getEstimatedNetworkUploadBytes() == ESTIMATED_UPLOAD_BYTES) && + jobInfo.getEstimatedNetworkDownloadBytes() == ESTIMATED_DOWNLOAD_BYTES && + jobInfo.getEstimatedNetworkUploadBytes() == ESTIMATED_UPLOAD_BYTES && jobInfo.getIntervalMillis() == intervalMillis && jobInfo.getFlexMillis() == flexMillis) { Log.d(TAG, "job already registered"); @@ -100,10 +99,8 @@ static void schedule(final Context context, int interval) { if (jobInfo == null) { final JobInfo.Builder builder = new JobInfo.Builder(FIRST_RUN_JOB_ID, serviceName) .setPersisted(true) - .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - builder.setEstimatedNetworkBytes(ESTIMATED_DOWNLOAD_BYTES, ESTIMATED_UPLOAD_BYTES); - } + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) + .setEstimatedNetworkBytes(ESTIMATED_DOWNLOAD_BYTES, ESTIMATED_UPLOAD_BYTES); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setExpedited(true); } @@ -117,10 +114,8 @@ static void schedule(final Context context, int interval) { final JobInfo.Builder builder = new JobInfo.Builder(PERIODIC_JOB_ID, serviceName) .setPeriodic(intervalMillis, flexMillis) .setPersisted(true) - .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - builder.setEstimatedNetworkBytes(ESTIMATED_DOWNLOAD_BYTES, ESTIMATED_UPLOAD_BYTES); - } + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) + .setEstimatedNetworkBytes(ESTIMATED_DOWNLOAD_BYTES, ESTIMATED_UPLOAD_BYTES); if (scheduler.schedule(builder.build()) == JobScheduler.RESULT_FAILURE) { throw new RuntimeException("job schedule failed"); } diff --git a/app/src/main/java/app/attestation/auditor/SubmitSampleJob.java b/app/src/main/java/app/attestation/auditor/SubmitSampleJob.java index ee60553ba..f2a7bb696 100644 --- a/app/src/main/java/app/attestation/auditor/SubmitSampleJob.java +++ b/app/src/main/java/app/attestation/auditor/SubmitSampleJob.java @@ -63,10 +63,8 @@ static void schedule(final Context context) { final JobScheduler scheduler = context.getSystemService(JobScheduler.class); final JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, serviceName) .setPersisted(true) - .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - builder.setEstimatedNetworkBytes(ESTIMATED_DOWNLOAD_BYTES, ESTIMATED_UPLOAD_BYTES); - } + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) + .setEstimatedNetworkBytes(ESTIMATED_DOWNLOAD_BYTES, ESTIMATED_UPLOAD_BYTES); if (scheduler.schedule(builder.build()) == JobScheduler.RESULT_FAILURE) { throw new RuntimeException("job schedule failed"); } @@ -96,17 +94,15 @@ public boolean onStartJob(final JobParameters params) { keyStore.deleteEntry(KEYSTORE_ALIAS_SAMPLE); Certificate[] strongBoxCerts = null; - if (Build.VERSION.SDK_INT >= 28) { - try { - builder.setIsStrongBoxBacked(true); - AttestationProtocol.generateKeyPair(builder.build()); - strongBoxCerts = keyStore.getCertificateChain(KEYSTORE_ALIAS_SAMPLE); - keyStore.deleteEntry(KEYSTORE_ALIAS_SAMPLE); - } catch (final StrongBoxUnavailableException ignored) { - } catch (final IOException e) { - if (!(e.getCause() instanceof StrongBoxUnavailableException)) { - throw e; - } + try { + builder.setIsStrongBoxBacked(true); + AttestationProtocol.generateKeyPair(builder.build()); + strongBoxCerts = keyStore.getCertificateChain(KEYSTORE_ALIAS_SAMPLE); + keyStore.deleteEntry(KEYSTORE_ALIAS_SAMPLE); + } catch (final StrongBoxUnavailableException ignored) { + } catch (final IOException e) { + if (!(e.getCause() instanceof StrongBoxUnavailableException)) { + throw e; } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e0d47c740..30b3a932e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ Auditor - Two devices are needed to perform verification:\n\n- The device to be verified (Auditee), which needs to be one of the supported devices launched with Android 8.0+.\n\n- An Android 8.0+ device to perform the verification (Auditor).\n\nThe verification process requires sending data between the devices by scanning QR codes. + Two devices with Android 10 or higher are needed to perform verification:\n\n- The device to be verified (Auditee), which needs to be one of the supported devices.\n\n- An Android device to perform the verification (Auditor).\n\nThe verification process requires sending data between the devices by scanning QR codes. Device is not one of the supported models. Camera permission is required to scan QR codes. Auditee (device being verified)