You've already forked TrickyStore
mirror of
https://github.com/5ec1cff/TrickyStore.git
synced 2025-09-06 06:37:07 +00:00
test: forward play certificate chain to key attestation app
This commit is contained in:
@@ -3,6 +3,7 @@ package io.github.a13e300.tricky_store
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.pm.IPackageManager
|
||||
import android.os.IBinder
|
||||
import android.os.IBinder.DeathRecipient
|
||||
import android.os.Parcel
|
||||
import android.os.ServiceManager
|
||||
import android.system.keystore2.IKeystoreService
|
||||
@@ -10,6 +11,7 @@ import android.system.keystore2.KeyEntryResponse
|
||||
import io.github.a13e300.tricky_store.binder.BinderInterceptor
|
||||
import io.github.a13e300.tricky_store.keystore.CertHack
|
||||
import io.github.a13e300.tricky_store.keystore.Utils
|
||||
import java.security.cert.Certificate
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
@SuppressLint("BlockedPrivateApi")
|
||||
@@ -37,12 +39,24 @@ object KeystoreInterceptor : BinderInterceptor() {
|
||||
Logger.d("intercept pre $target uid=$callingUid pid=$callingPid dataSz=${data.dataSize()}")
|
||||
kotlin.runCatching {
|
||||
val ps = getPm()?.getPackagesForUid(callingUid)
|
||||
if (ps?.contains("com.google.android.gms") == true) {
|
||||
gmsUid = callingUid
|
||||
Logger.d("gms uid $gmsUid")
|
||||
}
|
||||
if (ps?.contains("io.github.vvb2060.keyattestation") == true) {
|
||||
kaUid = callingUid
|
||||
Logger.d("ka uid $kaUid")
|
||||
}
|
||||
if (ps?.any { it in Config.targetPackages } == true) return Continue
|
||||
}.onFailure { Logger.e("failed to get packages", it) }
|
||||
}
|
||||
return Skip
|
||||
}
|
||||
|
||||
private var playCertificates: Array<Certificate>? = null
|
||||
private var gmsUid = 0
|
||||
private var kaUid = 0
|
||||
|
||||
override fun onPostTransact(
|
||||
target: IBinder,
|
||||
code: Int,
|
||||
@@ -61,7 +75,14 @@ object KeystoreInterceptor : BinderInterceptor() {
|
||||
val response = reply.readTypedObject(KeyEntryResponse.CREATOR)
|
||||
val chain = Utils.getCertificateChain(response)
|
||||
if (chain != null) {
|
||||
val newChain = CertHack.engineGetCertificateChain(chain)
|
||||
val newChain = if (callingUid == kaUid && playCertificates != null) {
|
||||
Logger.d("send play certificates to ka!")
|
||||
playCertificates
|
||||
} else CertHack.engineGetCertificateChain(chain)
|
||||
if (callingUid == gmsUid && CertHack.hasAttestation(chain)) {
|
||||
Logger.d("get play certificates!")
|
||||
playCertificates = newChain
|
||||
}
|
||||
Utils.putCertificateChain(response, newChain)
|
||||
p.writeNoException()
|
||||
p.writeTypedObject(response, 0)
|
||||
@@ -99,10 +120,14 @@ object KeystoreInterceptor : BinderInterceptor() {
|
||||
return false
|
||||
}
|
||||
registerBinderInterceptor(bd, b, this)
|
||||
b.linkToDeath({
|
||||
Logger.d("keystore exit, daemon restart")
|
||||
exitProcess(0)
|
||||
}, 0)
|
||||
b.linkToDeath(Killer, 0)
|
||||
return true
|
||||
}
|
||||
|
||||
object Killer : DeathRecipient {
|
||||
override fun binderDied() {
|
||||
Logger.d("keystore exit, daemon restart")
|
||||
exitProcess(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,17 @@ public final class CertHack {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasAttestation(Certificate[] caList) {
|
||||
if (caList == null) return false;
|
||||
try {
|
||||
X509Certificate leaf = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(caList[0].getEncoded()));
|
||||
byte[] bytes = leaf.getExtensionValue(OID.getId());
|
||||
return bytes != null;
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Certificate[] engineGetCertificateChain(Certificate[] caList) {
|
||||
if (caList == null) throw new UnsupportedOperationException("caList is null!");
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user