Skip to content

Commit

Permalink
app: generate key using SAK when available
Browse files Browse the repository at this point in the history
Signed-off-by: BlackMesa123 <giangrecosalvo9@gmail.com>
  • Loading branch information
salvogiangri committed Jan 23, 2024
1 parent 7b3a63b commit 3270394
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 3 deletions.
8 changes: 8 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
android:name="${applicationId}.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"
tools:node="remove" />

<uses-permission
android:name="com.samsung.android.security.permission.SAMSUNG_KEYSTORE_PERMISSION" />

<application
android:name=".AppApplication"
android:icon="@drawable/ic_launcher"
Expand All @@ -19,6 +22,11 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="AllowBackup">

<uses-library
android:name="samsungkeystoreutils"
android:required="false" />

<activity
android:name=".home.HomeActivity"
android:exported="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import android.widget.Toast
import androidx.core.content.edit
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.samsung.android.security.keystore.AttestParameterSpec
import com.samsung.android.security.keystore.AttestationUtils
import io.github.vvb2060.keyattestation.AppApplication
import io.github.vvb2060.keyattestation.attestation.AttestationResult
import io.github.vvb2060.keyattestation.attestation.CertificateInfo.parseCertificateChain
Expand All @@ -30,6 +32,7 @@ import io.github.vvb2060.keyattestation.lang.AttestationException.Companion.CODE
import io.github.vvb2060.keyattestation.lang.AttestationException.Companion.CODE_UNAVAILABLE_TRANSIENT
import io.github.vvb2060.keyattestation.lang.AttestationException.Companion.CODE_UNKNOWN
import io.github.vvb2060.keyattestation.util.Resource
import io.github.vvb2060.keyattestation.util.SamsungUtils
import java.io.BufferedInputStream
import java.io.ByteArrayInputStream
import java.io.IOException
Expand Down Expand Up @@ -112,10 +115,25 @@ class HomeViewModel(pm: PackageManager, private val sp: SharedPreferences) : Vie
builder.setAttestKeyAlias(attestKeyAlias)
}
}
val keyPairGenerator = KeyPairGenerator.getInstance(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && SamsungUtils.isSecAttestationSupported()) {
val spec = AttestParameterSpec.Builder(alias, now.toString().toByteArray())
.setAlgorithm(KeyProperties.KEY_ALGORITHM_EC)
.setKeyGenParameterSpec(builder.build())
.setVerifiableIntegrity(true)
.setPackageName(AppApplication.app.packageName)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && includeProps) {
spec.setDevicePropertiesAttestationIncluded(true)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && attestKey) {
spec.setCertificateSubject(X500Principal("CN=App Attest Key"))
}
AttestationUtils().generateKeyPair(spec.build())
} else {
val keyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore")
keyPairGenerator.initialize(builder.build())
keyPairGenerator.generateKeyPair()
keyPairGenerator.initialize(builder.build())
keyPairGenerator.generateKeyPair()
}
}

@Throws(AttestationException::class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package io.github.vvb2060.keyattestation.util

import android.content.pm.PackageManager
import android.os.SystemProperties
import android.util.Log
import androidx.core.content.ContextCompat
import io.github.vvb2060.keyattestation.AppApplication

object SamsungUtils {
private const val SAMSUNG_KEYSTORE_PERMISSION =
"com.samsung.android.security.permission.SAMSUNG_KEYSTORE_PERMISSION"

fun isSecAttestationSupported(): Boolean {
if (!isSamsungKeystoreLibrarySupported()) {
Log.w(AppApplication.TAG, "This device has no samsungkeystoreutils library, " +
"skipping SAK.")
return false
}

if (!isSAKSupported()) {
Log.w(AppApplication.TAG, "This device has no SAK support, " +
"skipping SAK.")
return false
}

if (!isKeystorePermissionGranted()) {
Log.e(AppApplication.TAG, "SAMSUNG_KEYSTORE_PERMISSION has not been granted to the app, " +
"skipping SAK.")
return false
}

return true
}

private fun isSamsungKeystoreLibrarySupported(): Boolean {
val pm: PackageManager = AppApplication.app.packageManager
val systemSharedLibraries = pm.systemSharedLibraryNames

if (systemSharedLibraries != null) {
for (lib in systemSharedLibraries) {
if (lib != null && lib.lowercase() == "samsungkeystoreutils") {
return true
}
}
}

return false
}

private fun isSAKSupported(): Boolean {
return SystemProperties.get("ro.security.keystore.keytype", "").lowercase()
.contains("sak")
}

private fun isKeystorePermissionGranted(): Boolean{
return ContextCompat.checkSelfPermission(
AppApplication.app, SAMSUNG_KEYSTORE_PERMISSION) ==
PackageManager.PERMISSION_GRANTED
}
}

0 comments on commit 3270394

Please sign in to comment.