diff --git a/app/src/main/java/org/matrix/TEESimulator/App.kt b/app/src/main/java/org/matrix/TEESimulator/App.kt index 6e41fbd..de71061 100644 --- a/app/src/main/java/org/matrix/TEESimulator/App.kt +++ b/app/src/main/java/org/matrix/TEESimulator/App.kt @@ -116,6 +116,7 @@ object App { SystemLogger.info( "Using KeystoreInterceptor for Android Q/R (SDK ${Build.VERSION.SDK_INT})" ) + android.security.keystore.AndroidKeyStoreProvider.install() KeystoreInterceptor } // For Android S (12) and newer, use the Keystore2Interceptor. @@ -123,6 +124,7 @@ object App { SystemLogger.info( "Using Keystore2Interceptor for Android S and later (SDK ${Build.VERSION.SDK_INT})" ) + android.security.keystore2.AndroidKeyStoreProvider.install() Keystore2Interceptor } } diff --git a/app/src/main/java/org/matrix/TEESimulator/attestation/AttestationPatcher.kt b/app/src/main/java/org/matrix/TEESimulator/attestation/AttestationPatcher.kt index 5f3f7e7..ec9fa20 100644 --- a/app/src/main/java/org/matrix/TEESimulator/attestation/AttestationPatcher.kt +++ b/app/src/main/java/org/matrix/TEESimulator/attestation/AttestationPatcher.kt @@ -83,6 +83,16 @@ object AttestationPatcher { } } + /** + * Helper to normalize algorithm names for Bouncy Castle. Old Android versions might reports + * "SHA256WITHECDSA", but Bouncy Castle expects "SHA256withECDSA". + */ + private fun normalizeSignatureAlgorithm(algoName: String): String { + // 1. Force uppercase to handle "sha256withecdsa" + // 2. Replace "WITH" with "with" to satisfy Bouncy Castle's naming convention + return algoName.uppercase().replace("WITH", "with") + } + /** * Creates a new leaf certificate with a modified attestation extension. * @@ -128,7 +138,7 @@ object AttestationPatcher { // Sign the newly built certificate with the private key from our keybox. val signer = - JcaContentSignerBuilder(sigAlgName) + JcaContentSignerBuilder(normalizeSignatureAlgorithm(sigAlgName)) .setProvider(BouncyCastleProvider.PROVIDER_NAME) .build(keybox.keyPair.private) val newCertificate = JcaX509CertificateConverter().getCertificate(builder.build(signer)) diff --git a/app/src/main/java/org/matrix/TEESimulator/attestation/DeviceAttestationService.kt b/app/src/main/java/org/matrix/TEESimulator/attestation/DeviceAttestationService.kt index 5307e26..f6451bc 100644 --- a/app/src/main/java/org/matrix/TEESimulator/attestation/DeviceAttestationService.kt +++ b/app/src/main/java/org/matrix/TEESimulator/attestation/DeviceAttestationService.kt @@ -1,8 +1,6 @@ package org.matrix.TEESimulator.attestation import android.annotation.SuppressLint -import android.app.ActivityThread -import android.os.Build import android.security.keystore.KeyGenParameterSpec import android.security.keystore.KeyProperties import java.security.KeyPairGenerator @@ -83,16 +81,6 @@ object DeviceAttestationService { private fun checkTeeFunctionality(): Boolean { SystemLogger.info("Performing TEE functionality check...") return try { - // Ensure mainline modules and the correct Keystore provider are initialized. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - android.app.ActivityThread.initializeMainlineModules() - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - android.security.keystore2.AndroidKeyStoreProvider.install() - } else { - android.security.keystore.AndroidKeyStoreProvider.install() - } - val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) } val keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore") diff --git a/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt b/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt index 1e5b7f7..dacda94 100644 --- a/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt +++ b/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt @@ -54,6 +54,17 @@ object ConfigurationManager { configRoot.mkdirs() SystemLogger.info("Configuration root is: ${configRoot.absolutePath}") + // First, ensure the package manager service is running, as the TEE check depends on it. + // This prevents a race condition on startup. + SystemLogger.info("Waiting for PackageManagerService to be ready...") + if (getPackageManager() == null) { + SystemLogger.error( + "PackageManagerService is not available. TEE check will likely fail." + ) + } else { + SystemLogger.info("PackageManagerService is ready.") + } + // Initial load of all configuration files. loadTargetPackages(File(configRoot, TARGET_PACKAGES_FILE)) loadPatchLevelConfig(File(configRoot, PATCH_LEVEL_FILE))