diff --git a/app/src/main/assets/fido2_privileged_community.json b/app/src/main/assets/fido2_privileged_community.json new file mode 100644 index 000000000..27eb8b5bc --- /dev/null +++ b/app/src/main/assets/fido2_privileged_community.json @@ -0,0 +1,64 @@ +{ + "apps": [ + { + "type": "android", + "info": { + "package_name": "io.github.forkmaintainers.iceraven", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "9C:0D:22:37:9F:48:7B:70:A4:F9:F8:BE:C0:17:3C:F9:1A:16:44:F0:8F:93:38:5B:5B:78:2C:E3:76:60:BA:81" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "org.chromium.chrome", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "A8:56:48:50:79:BC:B3:57:BF:BE:69:BA:19:A9:BA:43:CD:0A:D9:AB:22:67:52:C7:80:B6:88:8A:FD:48:21:6B" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "org.cromite.cromite", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "63:3F:A4:1D:82:11:D6:D0:91:6A:81:9B:89:66:8C:6D:E9:2E:64:23:2D:A6:7F:9D:16:FD:81:C3:B7:E9:23:FF" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "org.ironfoxoss.ironfox", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "C5:E2:91:B5:A5:71:F9:C8:CD:9A:97:99:C2:C9:4E:02:EC:97:03:94:88:93:F2:CA:75:6D:67:B9:42:04:F9:04" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "org.mozilla.fennec_fdroid", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "06:66:53:58:EF:D8:BA:05:BE:23:6A:47:A1:2C:B0:95:8D:7D:75:DD:93:9D:77:C2:B3:1F:53:98:53:7E:BD:C5" + } + ] + } + } + ] +} diff --git a/app/src/main/assets/trustedPackages.json b/app/src/main/assets/fido2_privileged_google.json similarity index 65% rename from app/src/main/assets/trustedPackages.json rename to app/src/main/assets/fido2_privileged_google.json index 8a24f37bb..47ada3cdf 100644 --- a/app/src/main/assets/trustedPackages.json +++ b/app/src/main/assets/fido2_privileged_google.json @@ -151,11 +151,11 @@ { "type": "android", "info": { - "package_name": "org.mozilla.fennec_fdroid", + "package_name": "org.mozilla.rocket", "signatures": [ { "build": "release", - "cert_fingerprint_sha256": "06:66:53:58:EF:D8:BA:05:BE:23:6A:47:A1:2C:B0:95:8D:7D:75:DD:93:9D:77:C2:B3:1F:53:98:53:7E:BD:C5" + "cert_fingerprint_sha256": "86:3A:46:F0:97:39:32:B7:D0:19:9B:54:91:12:74:1C:2D:27:31:AC:72:EA:11:B7:52:3A:A9:0A:11:BF:56:91" } ] } @@ -163,11 +163,71 @@ { "type": "android", "info": { - "package_name": "org.mozilla.rocket", + "package_name": "org.mozilla.fenix", "signatures": [ { "build": "release", - "cert_fingerprint_sha256": "86:3A:46:F0:97:39:32:B7:D0:19:9B:54:91:12:74:1C:2D:27:31:AC:72:EA:11:B7:52:3A:A9:0A:11:BF:56:91" + "cert_fingerprint_sha256": "50:04:77:90:88:E7:F9:88:D5:BC:5C:C5:F8:79:8F:EB:F4:F8:CD:08:4A:1B:2A:46:EF:D4:C8:EE:4A:EA:F2:11" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "org.mozilla.fenix.debug", + "signatures": [ + { + "build": "userdebug", + "cert_fingerprint_sha256": "BD:AE:82:02:80:D2:AF:B7:74:94:EF:22:58:AA:78:A9:AE:A1:36:41:7E:8B:C2:3D:C9:87:75:2E:6F:48:E8:48" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "org.mozilla.focus.beta", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "62:03:A4:73:BE:36:D6:4E:E3:7F:87:FA:50:0E:DB:C7:9E:AB:93:06:10:AB:9B:9F:A4:CA:7D:5C:1F:1B:4F:FC" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "org.mozilla.focus.nightly", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "62:03:A4:73:BE:36:D6:4E:E3:7F:87:FA:50:0E:DB:C7:9E:AB:93:06:10:AB:9B:9F:A4:CA:7D:5C:1F:1B:4F:FC" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "org.mozilla.klar", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "62:03:A4:73:BE:36:D6:4E:E3:7F:87:FA:50:0E:DB:C7:9E:AB:93:06:10:AB:9B:9F:A4:CA:7D:5C:1F:1B:4F:FC" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "org.mozilla.reference.browser", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "B0:09:90:E3:0F:9D:81:5D:2E:BC:7B:9B:B2:21:CE:47:E5:C9:D5:17:AA:C7:0E:7F:D5:95:B1:E5:3E:9A:4B:14" } ] } @@ -543,6 +603,218 @@ } ] } + }, + { + "type": "android", + "info": { + "package_name": "com.naver.whale", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "0B:8B:85:23:BB:4A:EF:FA:34:6E:4B:DD:4F:BF:7D:19:34:50:56:9A:A1:4A:AA:D4:AD:FD:94:A3:F7:B2:27:BB" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "com.fido.fido2client", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "FC:98:DA:E6:3A:D3:96:26:C8:C6:7F:BE:83:F2:F0:6F:74:93:2A:9C:D1:46:B9:2C:EC:FC:6A:04:7A:90:43:86" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "com.heytap.browser", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "AF:F8:A7:49:CF:0E:7D:75:44:65:D0:FB:FA:7B:8D:0C:64:5E:22:5C:10:C6:E2:32:AD:A0:D9:74:88:36:B8:E5" + }, + { + "build": "release", + "cert_fingerprint_sha256": "A8:FE:A4:CA:FB:93:32:DA:26:B8:E6:81:08:17:C1:DA:90:A5:03:0E:35:A6:0A:79:E0:6C:90:97:AA:C6:A4:42" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "io.island.Island", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "D9:C3:39:AC:9C:3A:EE:E1:75:1D:85:8C:35:D9:BA:C5:CC:87:B3:CE:76:30:93:F0:F5:10:64:F5:A2:F6:9B:04" + }, + { + "build": "userdebug", + "cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "io.island.IslandCanary", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "90:17:13:23:45:6E:6F:39:CB:FD:CF:B2:56:BE:1D:CF:F3:BC:1C:59:8A:15:93:30:E4:97:73:D0:4C:B9:C9:05" + }, + { + "build": "userdebug", + "cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "io.island.IslandBeta", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "35:31:83:1A:9E:2B:21:1D:E6:AA:C3:69:4B:45:83:6E:56:09:B9:D7:D0:04:C3:1B:21:87:40:FB:77:17:38:D1" + }, + { + "build": "userdebug", + "cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "io.island.IslandDev", + "signatures": [ + { + "build": "userdebug", + "cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "io.island.island.intune", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "C2:38:24:15:41:20:A0:8F:C3:95:42:AC:D8:2A:E9:24:94:78:80:1E:47:FD:6C:66:2B:18:1C:28:CA:7E:59:4E" + }, + { + "build": "userdebug", + "cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "io.island.island.canary.intune", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "1E:16:74:BB:79:EA:09:FB:37:CF:9F:1B:07:1B:1D:51:8D:46:03:0E:D3:EE:F2:C1:4E:AD:93:9E:C6:EE:3A:4C" + }, + { + "build": "userdebug", + "cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "io.island.island.beta.intune", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "D2:5E:AD:F6:1C:E6:36:6C:A4:23:A4:7F:C4:DB:9B:8C:9C:8A:35:B4:B0:19:E8:D9:82:FB:D0:8A:D9:DB:49:5A" + }, + { + "build": "userdebug", + "cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "io.island.island.dev.intune", + "signatures": [ + { + "build": "userdebug", + "cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "net.quetta.browser", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "BE:FE:E7:31:12:6A:A5:6E:7E:FD:AE:AF:5E:F3:FA:EA:44:1C:19:CC:E0:CA:EC:42:6B:65:BB:F8:2C:59:46:80" + }, + { + "build": "userdebug", + "cert_fingerprint_sha256": "F1:38:00:4F:38:04:51:D4:8A:05:2B:B3:A3:EF:17:24:23:D4:B0:D0:C8:A3:AA:DD:FB:DB:66:30:31:48:EC:A4" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "cz.seznam.sbrowser", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "DB:95:40:66:10:78:83:6E:4E:B1:66:F6:9E:F4:07:30:9E:8D:AE:33:34:68:5E:C8:F6:FA:2F:13:81:B9:AC:F6" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "com.opera.mini.native", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "57:AC:BC:52:5F:1B:2E:BD:19:19:6C:D6:F0:14:39:7C:C9:10:FD:18:84:1E:0A:E8:50:FE:BC:3E:1E:59:3F:F2" + } + ] + } + }, + { + "type": "android", + "info": { + "package_name": "com.opera.mini.native.beta", + "signatures": [ + { + "build": "release", + "cert_fingerprint_sha256": "57:AC:BC:52:5F:1B:2E:BD:19:19:6C:D6:F0:14:39:7C:C9:10:FD:18:84:1E:0A:E8:50:FE:BC:3E:1E:59:3F:F2" + } + ] + } } ] } \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/passkey/util/PasskeyHelper.kt b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/passkey/util/PasskeyHelper.kt index b5a360f71..2590adc5b 100644 --- a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/passkey/util/PasskeyHelper.kt +++ b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/passkey/util/PasskeyHelper.kt @@ -42,6 +42,7 @@ import androidx.credentials.provider.ProviderGetCredentialRequest import com.kunzisoft.encrypt.Base64Helper.Companion.b64Encode import com.kunzisoft.encrypt.Signature import com.kunzisoft.encrypt.Signature.getApplicationFingerprints +import com.kunzisoft.keepass.BuildConfig import com.kunzisoft.keepass.credentialprovider.passkey.data.AuthenticatorAssertionResponse import com.kunzisoft.keepass.credentialprovider.passkey.data.AuthenticatorAttestationResponse import com.kunzisoft.keepass.credentialprovider.passkey.data.Cbor @@ -327,9 +328,19 @@ object PasskeyHelper { return request.credentialOptions[0] as GetPublicKeyCredentialOption } + private fun getOriginFromPrivilegedAllowList( + callingAppInfo: CallingAppInfo, + assets: AssetManager, + fileName: String): String? { + val privilegedAllowList = assets.open(fileName).bufferedReader().use { + it.readText() + } + return callingAppInfo.getOrigin(privilegedAllowList)?.removeSuffix("/") + } + /** * Utility method to retrieve the origin asynchronously, - * checks for the presence of the application in the privilege list of the trustedPackages.json file, + * checks for the presence of the application in the privilege list of the fido2_privileged_google.json file, * call [onOriginRetrieved] if the origin is already calculated by the system and in the privileged list, return the clientDataHash * call [onOriginNotRetrieved] if the origin is not retrieved from the system, return a new Android Origin */ @@ -344,16 +355,33 @@ object PasskeyHelper { throw SecurityException("Calling app info cannot be retrieved") } withContext(Dispatchers.IO) { - var callOrigin: String? - val privilegedAllowlist = assets.open("trustedPackages.json").bufferedReader().use { - it.readText() + + // For trusted browsers like Chrome and Firefox + // Check the community apps first + val callOrigin = try { + getOriginFromPrivilegedAllowList( + callingAppInfo, + assets, + "fido2_privileged_community.json" + ) + } catch (e: Exception) { + // Then the Google list if allowed + if (BuildConfig.CLOSED_STORE) { + getOriginFromPrivilegedAllowList( + callingAppInfo, + assets, + "fido2_privileged_google.json" + ) + } else { + throw e + } } - // for trusted browsers like Chrome and Firefox - callOrigin = callingAppInfo.getOrigin(privilegedAllowlist)?.removeSuffix("/") + val androidOrigin = AndroidOrigin( packageName = callingAppInfo.packageName, fingerprint = callingAppInfo.signingInfo.getApplicationFingerprints() ) + // Check if the webDomain is validated for the withContext(Dispatchers.Main) { if (callOrigin != null && providedClientDataHash != null) {