From 76424a7ead75ca471f0f26ee2baa661c80ab5dd5 Mon Sep 17 00:00:00 2001 From: Kai Widmer Date: Fri, 28 Apr 2023 08:17:39 +0200 Subject: [PATCH 1/2] [google-play-integrity] Use play integrity as google attestation provider --- gradle.properties | 2 +- multiplatform/build.gradle | 2 +- .../GoogleAttestationProvider.kt | 24 ++++++++++++------- .../multiplatform/DreiAttestService.kt | 2 +- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/gradle.properties b/gradle.properties index dc82454..dc0cdf4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -34,7 +34,7 @@ versions_kermit=0.1.9 versions_mpf_settings=0.8.1 #android -versions_safety_net=18.0.1 +versions_play_integrity=1.1.0 versions_play_services_coroutines=1.6.0 #iOS \ No newline at end of file diff --git a/multiplatform/build.gradle b/multiplatform/build.gradle index 57a9c6d..6ed5381 100644 --- a/multiplatform/build.gradle +++ b/multiplatform/build.gradle @@ -39,7 +39,7 @@ kotlin { } sourceSets["androidMain"].dependencies { - implementation "com.google.android.gms:play-services-safetynet:$versions_safety_net" + implementation "com.google.android.play:integrity:$versions_play_integrity" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$versions_play_services_coroutines" implementation("io.ktor:ktor-client-android:$versions_ktor") } diff --git a/multiplatform/src/androidMain/kotlin/ch/dreipol/dreiattest/multiplatform/GoogleAttestationProvider.kt b/multiplatform/src/androidMain/kotlin/ch/dreipol/dreiattest/multiplatform/GoogleAttestationProvider.kt index 5d5e3d6..b05c1c6 100644 --- a/multiplatform/src/androidMain/kotlin/ch/dreipol/dreiattest/multiplatform/GoogleAttestationProvider.kt +++ b/multiplatform/src/androidMain/kotlin/ch/dreipol/dreiattest/multiplatform/GoogleAttestationProvider.kt @@ -1,24 +1,30 @@ package ch.dreipol.dreiattest.multiplatform import android.content.Context +import android.util.Base64 import ch.dreipol.dreiattest.multiplatform.api.dto.Attestation import ch.dreipol.dreiattest.multiplatform.utils.DeviceSystemInfo import ch.dreipol.dreiattest.multiplatform.utils.Hash import ch.dreipol.dreiattest.multiplatform.utils.SystemInfo -import com.google.android.gms.common.ConnectionResult -import com.google.android.gms.common.GoogleApiAvailability -import com.google.android.gms.safetynet.SafetyNet +import com.google.android.play.core.integrity.IntegrityManagerFactory +import com.google.android.play.core.integrity.IntegrityTokenRequest import kotlinx.coroutines.tasks.await -internal const val platformDriver = "google" +internal const val platformDriver = "google_play_integrity_api" -public class GoogleAttestationProvider(private val context: Context, private val apiKey: String) : AttestationProvider { +class GoogleAttestationProvider(private val context: Context, private val cloudProjectNumber: Long? = null) : AttestationProvider { + private val integrityManager by lazy { + IntegrityManagerFactory.create(context) + } override val systemInfo: SystemInfo = DeviceSystemInfo(context) - override val isSupported: Boolean = - GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS + override val isSupported: Boolean = true + - public override suspend fun getAttestation(nonce: Hash, publicKey: String): Attestation { - val deviceAttestation = SafetyNet.getClient(context).attest(nonce, apiKey).await().jwsResult!! + override suspend fun getAttestation(nonce: Hash, publicKey: String): Attestation { + val requestBuilder = IntegrityTokenRequest.builder() + .setNonce(Base64.encodeToString(nonce, Base64.URL_SAFE or Base64.NO_WRAP)) + cloudProjectNumber?.let { requestBuilder.setCloudProjectNumber(it) } + val deviceAttestation = integrityManager.requestIntegrityToken(requestBuilder.build()).await().token() return Attestation(publicKey = publicKey, attestation = deviceAttestation, driver = platformDriver) } } \ No newline at end of file diff --git a/multiplatform/src/commonMain/kotlin/ch/dreipol/dreiattest/multiplatform/DreiAttestService.kt b/multiplatform/src/commonMain/kotlin/ch/dreipol/dreiattest/multiplatform/DreiAttestService.kt index 134e62f..b23bf75 100644 --- a/multiplatform/src/commonMain/kotlin/ch/dreipol/dreiattest/multiplatform/DreiAttestService.kt +++ b/multiplatform/src/commonMain/kotlin/ch/dreipol/dreiattest/multiplatform/DreiAttestService.kt @@ -73,8 +73,8 @@ public class DreiAttestService(private val keystore: Keystore = DeviceKeystore() val signatureNonce = middlewareAPI.getNonce(uid).trim('"') val publicKey = CryptoUtils.encodeToBase64(keystore.generateNewKeyPair(uid)) val nonce = CryptoUtils.hashSHA256((uid + publicKey + signatureNonce).toByteArray(Charsets.UTF_8)) - val attestation = sessionConfiguration.deviceAttestationProvider.getAttestation(nonce, publicKey) try { + val attestation = sessionConfiguration.deviceAttestationProvider.getAttestation(nonce, publicKey) middlewareAPI.setKey(attestation, uid, signatureNonce) } catch (t: Throwable) { keystore.deleteKeyPair(uid) From 7c2c7722ac8c79b183dfa121e495716a6c463115 Mon Sep 17 00:00:00 2001 From: Kai Widmer Date: Fri, 28 Apr 2023 08:17:47 +0200 Subject: [PATCH 2/2] [google-play-integrity] Update readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c6ccc4a..e322a69 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,8 @@ implementation("ch.dreipol.dreiattest.multiplatform:multiplatform-android: