Commit 94ec11db authored by topjohnwu's avatar topjohnwu

Update snet.jar extension

The existing API key was revoked for some reason.
Release an updated extension jar with a new API key.

In addition, add some offline signature verification and change how
results are parsed to workaround some dumbass Xposed module "faking"
success results, since many users really don't know better.
parent c4e8dda3
...@@ -207,7 +207,7 @@ dependencies { ...@@ -207,7 +207,7 @@ dependencies {
implementation("io.noties.markwon:image:${vMarkwon}") implementation("io.noties.markwon:image:${vMarkwon}")
implementation("com.caverock:androidsvg:1.4") implementation("com.caverock:androidsvg:1.4")
val vLibsu = "3.1.1" val vLibsu = "3.1.2"
implementation("com.github.topjohnwu.libsu:core:${vLibsu}") implementation("com.github.topjohnwu.libsu:core:${vLibsu}")
implementation("com.github.topjohnwu.libsu:io:${vLibsu}") implementation("com.github.topjohnwu.libsu:io:${vLibsu}")
......
...@@ -29,7 +29,7 @@ object Const { ...@@ -29,7 +29,7 @@ object Const {
const val MAGISK_LOG = "/cache/magisk.log" const val MAGISK_LOG = "/cache/magisk.log"
// Versions // Versions
const val SNET_EXT_VER = 15 const val SNET_EXT_VER = 16
const val SNET_REVISION = "22.0" const val SNET_REVISION = "22.0"
const val BOOTCTL_REVISION = "22.0" const val BOOTCTL_REVISION = "22.0"
......
package com.topjohnwu.magisk.data.repository package com.topjohnwu.magisk.data.repository
import android.os.Build
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Config.Value.BETA_CHANNEL import com.topjohnwu.magisk.core.Config.Value.BETA_CHANNEL
import com.topjohnwu.magisk.core.Config.Value.CANARY_CHANNEL import com.topjohnwu.magisk.core.Config.Value.CANARY_CHANNEL
...@@ -66,7 +65,7 @@ class NetworkService( ...@@ -66,7 +65,7 @@ class NetworkService(
} }
// Fetch files // Fetch files
suspend fun fetchSafetynet() = wrap { jsd.fetchSafetynet() } // suspend fun fetchSafetynet() = wrap { jsd.fetchSafetynet() }
suspend fun fetchBootctl() = wrap { jsd.fetchBootctl() } suspend fun fetchBootctl() = wrap { jsd.fetchBootctl() }
suspend fun fetchInstaller() = wrap { suspend fun fetchInstaller() = wrap {
val sha = fetchMainVersion() val sha = fetchMainVersion()
...@@ -76,4 +75,7 @@ class NetworkService( ...@@ -76,4 +75,7 @@ class NetworkService(
suspend fun fetchString(url: String) = wrap { raw.fetchString(url) } suspend fun fetchString(url: String) = wrap { raw.fetchString(url) }
private suspend fun fetchMainVersion() = api.fetchBranch(MAGISK_MAIN, "master").commit.sha private suspend fun fetchMainVersion() = api.fetchBranch(MAGISK_MAIN, "master").commit.sha
// Temporary for canary builds, switch to release link at next public release
suspend fun fetchSafetynet() = fetchFile("https://github.com/topjohnwu/Magisk/releases/download/v22.1/snet.jar")
} }
package com.topjohnwu.magisk.ui.safetynet package com.topjohnwu.magisk.ui.safetynet
import org.json.JSONObject
interface SafetyNetHelper { interface SafetyNetHelper {
val version: Int val version: Int
fun attest() fun attest(nonce: ByteArray)
interface Callback { interface Callback {
fun onResponse(response: JSONObject?) fun onResponse(response: String?)
} }
} }
...@@ -5,10 +5,9 @@ import com.topjohnwu.magisk.BR ...@@ -5,10 +5,9 @@ import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
import org.json.JSONObject
data class SafetyNetResult( data class SafetyNetResult(
val response: JSONObject? = null, val response: SafetyNetResponse? = null,
val dismiss: Boolean = false val dismiss: Boolean = false
) )
...@@ -43,20 +42,20 @@ class SafetynetViewModel : BaseViewModel() { ...@@ -43,20 +42,20 @@ class SafetynetViewModel : BaseViewModel() {
init { init {
cachedResult?.also { cachedResult?.also {
resolveResponse(SafetyNetResult(it)) handleResponse(SafetyNetResult(it))
} ?: attest() } ?: attest()
} }
private fun attest() { private fun attest() {
isChecking = true isChecking = true
CheckSafetyNetEvent { CheckSafetyNetEvent {
resolveResponse(it) handleResponse(it)
}.publish() }.publish()
} }
fun reset() = attest() fun reset() = attest()
private fun resolveResponse(response: SafetyNetResult) { private fun handleResponse(response: SafetyNetResult) {
isChecking = false isChecking = false
if (response.dismiss) { if (response.dismiss) {
...@@ -65,26 +64,15 @@ class SafetynetViewModel : BaseViewModel() { ...@@ -65,26 +64,15 @@ class SafetynetViewModel : BaseViewModel() {
} }
response.response?.apply { response.response?.apply {
runCatching { val result = ctsProfileMatch && basicIntegrity
val cts = getBoolean("ctsProfileMatch") cachedResult = this
val basic = getBoolean("basicIntegrity") ctsState = ctsProfileMatch
val eval = optString("evaluationType") basicIntegrityState = basicIntegrity
val result = cts && basic evalType = if (evaluationType.contains("HARDWARE")) "HARDWARE" else "BASIC"
cachedResult = this isSuccess = result
ctsState = cts safetyNetTitle =
basicIntegrityState = basic if (result) R.string.safetynet_attest_success
evalType = if (eval.contains("HARDWARE")) "HARDWARE" else "BASIC" else R.string.safetynet_attest_failure
isSuccess = result
safetyNetTitle =
if (result) R.string.safetynet_attest_success
else R.string.safetynet_attest_failure
}.onFailure {
isSuccess = false
ctsState = false
basicIntegrityState = false
evalType = "N/A"
safetyNetTitle = R.string.safetynet_res_invalid
}
} ?: { } ?: {
isSuccess = false isSuccess = false
ctsState = false ctsState = false
...@@ -95,7 +83,7 @@ class SafetynetViewModel : BaseViewModel() { ...@@ -95,7 +83,7 @@ class SafetynetViewModel : BaseViewModel() {
} }
companion object { companion object {
private var cachedResult: JSONObject? = null private var cachedResult: SafetyNetResponse? = null
} }
} }
...@@ -363,7 +363,7 @@ def build_stub(args): ...@@ -363,7 +363,7 @@ def build_stub(args):
def build_snet(args): def build_snet(args):
if not op.exists(op.join('snet', 'src', 'main', 'java', 'com', 'topjohnwu', 'snet')): if not op.exists(op.join('stub', 'src', 'main', 'java', 'com', 'topjohnwu', 'snet')):
error('snet sources have to be bind mounted on top of the stub folder') error('snet sources have to be bind mounted on top of the stub folder')
header('* Building snet extension') header('* Building snet extension')
proc = execv([gradlew, 'stub:assembleRelease']) proc = execv([gradlew, 'stub:assembleRelease'])
......
#Wed Apr 14 22:32:11 PDT 2021
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment