mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
fix: Add webOrigin, fix title and add verification state
This commit is contained in:
@@ -9,6 +9,7 @@ import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper
|
||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.isIntentSenderMode
|
||||
import com.kunzisoft.keepass.credentialprovider.SpecialMode
|
||||
import com.kunzisoft.keepass.credentialprovider.TypeMode
|
||||
import com.kunzisoft.keepass.model.RegisterInfo
|
||||
import com.kunzisoft.keepass.model.SearchInfo
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.view.ToolbarSpecial
|
||||
@@ -113,7 +114,8 @@ abstract class DatabaseModeActivity : DatabaseActivity() {
|
||||
|
||||
mSpecialMode = EntrySelectionHelper.retrieveSpecialModeFromIntent(intent)
|
||||
mTypeMode = EntrySelectionHelper.retrieveTypeModeFromIntent(intent)
|
||||
val searchInfo: SearchInfo? = EntrySelectionHelper.retrieveRegisterInfoFromIntent(intent)?.searchInfo
|
||||
val registerInfo: RegisterInfo? = EntrySelectionHelper.retrieveRegisterInfoFromIntent(intent)
|
||||
val searchInfo: SearchInfo? = registerInfo?.searchInfo
|
||||
?: EntrySelectionHelper.retrieveSearchInfoFromIntent(intent)
|
||||
|
||||
// To show the selection mode
|
||||
@@ -137,7 +139,7 @@ abstract class DatabaseModeActivity : DatabaseActivity() {
|
||||
if (mTypeMode != TypeMode.DEFAULT)
|
||||
title = "$title (${getString(typeModeStringId)})"
|
||||
// Populate subtitle
|
||||
subtitle = searchInfo?.getName(resources)
|
||||
subtitle = registerInfo?.getName(resources) ?: searchInfo?.getName(resources)
|
||||
|
||||
// Show the toolbar or not
|
||||
visible = when (mSpecialMode) {
|
||||
|
||||
@@ -48,7 +48,7 @@ import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.addSe
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.buildCreatePublicKeyCredentialResponse
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.buildPasskeyPublicKeyCredential
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.checkSecurity
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.getVerifiedClientDataResponse
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.getVerifiedGETClientDataResponse
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.removeAppOrigin
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.removePasskey
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.retrieveAppOrigin
|
||||
@@ -85,37 +85,31 @@ class PasskeyLauncherActivity : DatabaseModeActivity() {
|
||||
val responseIntent = Intent()
|
||||
try {
|
||||
Log.d(TAG, "Passkey selection result")
|
||||
val passkey = intent?.retrievePasskey()
|
||||
val appOrigin = intent?.retrieveAppOrigin()
|
||||
intent?.removePasskey()
|
||||
intent?.removeAppOrigin()
|
||||
passkey?.let {
|
||||
mUsageParameters?.let { usageParameters ->
|
||||
// Check verified origin
|
||||
getVerifiedClientDataResponse(
|
||||
usageParameters = usageParameters,
|
||||
appOrigin = appOrigin,
|
||||
onOriginChecked = { clientDataResponse ->
|
||||
PendingIntentHandler.setGetCredentialResponse(
|
||||
responseIntent,
|
||||
GetCredentialResponse(
|
||||
buildPasskeyPublicKeyCredential(
|
||||
requestOptions = usageParameters.publicKeyCredentialRequestOptions,
|
||||
clientDataResponse = clientDataResponse,
|
||||
passkey = passkey
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
onOriginNotChecked = {
|
||||
throw SecurityException("Wrong signature for ${usageParameters.androidApp.id}")
|
||||
}
|
||||
if (intent == null)
|
||||
throw IOException("Intent is null")
|
||||
val passkey = intent.retrievePasskey()
|
||||
?: throw IOException("Passkey is null")
|
||||
val appOrigin = intent.retrieveAppOrigin()
|
||||
?: throw IOException("App origin is null")
|
||||
intent.removePasskey()
|
||||
intent.removeAppOrigin()
|
||||
mUsageParameters?.let { usageParameters ->
|
||||
// Check verified origin
|
||||
PendingIntentHandler.setGetCredentialResponse(
|
||||
responseIntent,
|
||||
GetCredentialResponse(
|
||||
buildPasskeyPublicKeyCredential(
|
||||
requestOptions = usageParameters.publicKeyCredentialRequestOptions,
|
||||
clientDataResponse = getVerifiedGETClientDataResponse(
|
||||
usageParameters = usageParameters,
|
||||
appOrigin = appOrigin
|
||||
),
|
||||
passkey = passkey
|
||||
)
|
||||
)
|
||||
} ?: run {
|
||||
throw IOException("Usage parameters is null")
|
||||
}
|
||||
)
|
||||
} ?: run {
|
||||
throw IOException("Passkey is null")
|
||||
throw IOException("Usage parameters is null")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to create selection response for passkey", e)
|
||||
@@ -197,7 +191,8 @@ class PasskeyLauncherActivity : DatabaseModeActivity() {
|
||||
|
||||
private fun autoSelectPasskeyAndSetResult(
|
||||
database: ContextualDatabase?,
|
||||
nodeId: UUID
|
||||
nodeId: UUID,
|
||||
appOrigin: AppOrigin
|
||||
) {
|
||||
mUsageParameters?.let { usageParameters ->
|
||||
// To get the passkey from the database
|
||||
@@ -213,7 +208,10 @@ class PasskeyLauncherActivity : DatabaseModeActivity() {
|
||||
GetCredentialResponse(
|
||||
buildPasskeyPublicKeyCredential(
|
||||
requestOptions = usageParameters.publicKeyCredentialRequestOptions,
|
||||
clientDataResponse = usageParameters.clientDataResponse,
|
||||
clientDataResponse = getVerifiedGETClientDataResponse(
|
||||
usageParameters = usageParameters,
|
||||
appOrigin = appOrigin
|
||||
),
|
||||
passkey = passkey
|
||||
)
|
||||
)
|
||||
@@ -230,23 +228,20 @@ class PasskeyLauncherActivity : DatabaseModeActivity() {
|
||||
private suspend fun launchSelection(
|
||||
database: ContextualDatabase?,
|
||||
nodeId: UUID?,
|
||||
searchInfo: SearchInfo?,
|
||||
appOrigin: AppOrigin?
|
||||
searchInfo: SearchInfo,
|
||||
appOrigin: AppOrigin
|
||||
) {
|
||||
Log.d(TAG, "Launch passkey selection")
|
||||
retrievePasskeyUsageRequestParameters(
|
||||
intent = intent,
|
||||
assetManager = assets,
|
||||
appOrigin = appOrigin
|
||||
appOrigin = appOrigin,
|
||||
) { usageParameters ->
|
||||
// Save the requested parameters
|
||||
mUsageParameters = usageParameters
|
||||
// Manage the passkey to use
|
||||
nodeId?.let { nodeId ->
|
||||
if (usageParameters.androidAppVerified.not()) {
|
||||
throw SecurityException("Wrong signature for ${usageParameters.androidApp.id}")
|
||||
}
|
||||
autoSelectPasskeyAndSetResult(database, nodeId)
|
||||
autoSelectPasskeyAndSetResult(database, nodeId, appOrigin)
|
||||
} ?: run {
|
||||
SearchHelper.checkAutoSearchInfo(
|
||||
context = this,
|
||||
|
||||
@@ -19,11 +19,12 @@
|
||||
*/
|
||||
package com.kunzisoft.keepass.credentialprovider.passkey.data
|
||||
|
||||
import com.kunzisoft.keepass.model.AppIdentifier
|
||||
import com.kunzisoft.keepass.model.AndroidOrigin
|
||||
import com.kunzisoft.keepass.model.WebOrigin
|
||||
|
||||
data class PublicKeyCredentialUsageParameters(
|
||||
val publicKeyCredentialRequestOptions: PublicKeyCredentialRequestOptions,
|
||||
val clientDataResponse: ClientDataResponse,
|
||||
val androidApp: AppIdentifier,
|
||||
val androidAppVerified: Boolean
|
||||
val androidOrigin: AndroidOrigin,
|
||||
val webOrigin: WebOrigin,
|
||||
)
|
||||
@@ -25,8 +25,10 @@ import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.credentials.provider.CallingAppInfo
|
||||
import com.kunzisoft.encrypt.HashManager.getApplicationSignatures
|
||||
import com.kunzisoft.keepass.model.AppIdentifier
|
||||
import com.kunzisoft.keepass.model.AndroidOrigin
|
||||
import com.kunzisoft.keepass.model.AppOrigin
|
||||
import com.kunzisoft.keepass.model.Verification
|
||||
import com.kunzisoft.keepass.model.WebOrigin
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -37,7 +39,8 @@ import kotlinx.coroutines.withContext
|
||||
class OriginManager(
|
||||
private val providedClientDataHash: ByteArray?,
|
||||
private val callingAppInfo: CallingAppInfo?,
|
||||
private val assets: AssetManager
|
||||
private val assets: AssetManager,
|
||||
private val relyingParty: String,
|
||||
) {
|
||||
|
||||
/**
|
||||
@@ -50,20 +53,23 @@ class OriginManager(
|
||||
onOriginCreated: (appInfoToStore: AppOrigin, origin: String) -> Unit
|
||||
) {
|
||||
getOrigin(
|
||||
onOriginRetrieved = { appIdentifier, callOrigin, clientDataHash ->
|
||||
onOriginRetrieved = { androidOrigin, webOrigin, callOrigin, clientDataHash ->
|
||||
onOriginRetrieved(
|
||||
AppOrigin().apply {
|
||||
// Do not store Web Browser AppId -> addIdentifier(appIdentifier)
|
||||
addWebDomain(callOrigin)
|
||||
addAndroidOrigin(androidOrigin)
|
||||
addWebOrigin(webOrigin)
|
||||
},
|
||||
clientDataHash
|
||||
)
|
||||
},
|
||||
onOriginNotRetrieved = { appIdentifier ->
|
||||
onOriginNotRetrieved = { appIdentifier, webOrigin ->
|
||||
// Create a new Android Origin and prepare the signature app storage
|
||||
onOriginCreated(
|
||||
AppOrigin().apply { addIdentifier(appIdentifier) },
|
||||
appIdentifier.buildAndroidOrigin()
|
||||
AppOrigin().apply {
|
||||
addAndroidOrigin(appIdentifier)
|
||||
addWebOrigin(webOrigin)
|
||||
},
|
||||
appIdentifier.toAndroidOrigin()
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -75,25 +81,27 @@ class OriginManager(
|
||||
* calls [onOriginCreated] if the origin was created manually, origin is verified if present in the KeePass database
|
||||
*/
|
||||
suspend fun getOriginAtUsage(
|
||||
appOrigin: AppOrigin?,
|
||||
onOriginRetrieved: (appIdentifier: AppIdentifier, clientDataHash: ByteArray) -> Unit,
|
||||
onOriginCreated: (appIdentifier: AppIdentifier, origin: String, originVerified: Boolean) -> Unit
|
||||
appOrigin: AppOrigin,
|
||||
onOriginRetrieved: (androidOrigin: AndroidOrigin, webOrigin: WebOrigin, clientDataHash: ByteArray) -> Unit,
|
||||
onOriginCreated: (androidOrigin: AndroidOrigin, webOrigin: WebOrigin) -> Unit
|
||||
) {
|
||||
getOrigin(
|
||||
onOriginRetrieved = { appIdentifier, origin, clientDataHash ->
|
||||
onOriginRetrieved(appIdentifier, clientDataHash)
|
||||
onOriginRetrieved = { androidOrigin, webOrigin, origin, clientDataHash ->
|
||||
onOriginRetrieved(androidOrigin, webOrigin, clientDataHash)
|
||||
},
|
||||
onOriginNotRetrieved = { appIdentifierToCheck ->
|
||||
// Verify the app signature to retrieve the origin
|
||||
val androidOrigin = appIdentifierToCheck.buildAndroidOrigin()
|
||||
appIdentifierToCheck.checkInAppOrigin(
|
||||
appOrigin = appOrigin,
|
||||
onOriginChecked = {
|
||||
onOriginCreated(appIdentifierToCheck, androidOrigin, true)
|
||||
},
|
||||
onOriginNotChecked = {
|
||||
onOriginCreated(appIdentifierToCheck, androidOrigin, false)
|
||||
}
|
||||
onOriginNotRetrieved = { appIdentifierToCheck, webOrigin ->
|
||||
// Check the app signature in the appOrigin, webOrigin cannot be checked now
|
||||
onOriginCreated(
|
||||
AndroidOrigin(
|
||||
packageName = appIdentifierToCheck.packageName,
|
||||
signature = appIdentifierToCheck.signature,
|
||||
verification =
|
||||
if (appOrigin.containsVerifiedAndroidOrigin(appIdentifierToCheck))
|
||||
Verification.MANUALLY_VERIFIED
|
||||
else
|
||||
Verification.NOT_VERIFIED
|
||||
),
|
||||
webOrigin
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -106,8 +114,8 @@ class OriginManager(
|
||||
* call [onOriginNotRetrieved] if the origin is not retrieved from the system
|
||||
*/
|
||||
private suspend fun getOrigin(
|
||||
onOriginRetrieved: (appInfoRetrieved: AppIdentifier, origin: String, clientDataHash: ByteArray) -> Unit,
|
||||
onOriginNotRetrieved: (appInfoRetrieved: AppIdentifier) -> Unit
|
||||
onOriginRetrieved: (androidOrigin: AndroidOrigin, webOrigin: WebOrigin, origin: String, clientDataHash: ByteArray) -> Unit,
|
||||
onOriginNotRetrieved: (androidOrigin: AndroidOrigin, webOrigin: WebOrigin) -> Unit
|
||||
) {
|
||||
if (callingAppInfo == null) {
|
||||
throw SecurityException("Calling app info cannot be retrieved")
|
||||
@@ -119,17 +127,37 @@ class OriginManager(
|
||||
}
|
||||
// for trusted browsers like Chrome and Firefox
|
||||
callOrigin = callingAppInfo.getOrigin(privilegedAllowlist)?.removeSuffix("/")
|
||||
val appIdentifier = AppIdentifier(
|
||||
id = callingAppInfo.packageName,
|
||||
val androidOrigin = AndroidOrigin(
|
||||
packageName = callingAppInfo.packageName,
|
||||
signature = callingAppInfo.signingInfo
|
||||
.getApplicationSignatures()
|
||||
.getApplicationSignatures(),
|
||||
verification = Verification.NOT_VERIFIED
|
||||
)
|
||||
// Check if the webDomain is validated for the
|
||||
withContext(Dispatchers.Main) {
|
||||
if (callOrigin != null && providedClientDataHash != null) {
|
||||
Log.d(TAG, "Origin $callOrigin retrieved from callingAppInfo")
|
||||
onOriginRetrieved(appIdentifier, callOrigin, providedClientDataHash)
|
||||
onOriginRetrieved(
|
||||
AndroidOrigin(
|
||||
packageName = androidOrigin.packageName,
|
||||
signature = androidOrigin.signature,
|
||||
verification = Verification.AUTOMATICALLY_VERIFIED
|
||||
),
|
||||
WebOrigin.fromRelyingParty(
|
||||
relyingParty = relyingParty,
|
||||
verification = Verification.AUTOMATICALLY_VERIFIED
|
||||
),
|
||||
callOrigin,
|
||||
providedClientDataHash
|
||||
)
|
||||
} else {
|
||||
onOriginNotRetrieved(appIdentifier)
|
||||
onOriginNotRetrieved(
|
||||
androidOrigin,
|
||||
WebOrigin.fromRelyingParty(
|
||||
relyingParty = relyingParty,
|
||||
verification = Verification.NOT_VERIFIED
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,42 +165,5 @@ class OriginManager(
|
||||
|
||||
companion object {
|
||||
private val TAG = OriginManager::class.simpleName
|
||||
|
||||
/**
|
||||
* Verify that the application signature is contained in the [appOrigin]
|
||||
*/
|
||||
fun AppIdentifier.checkInAppOrigin(
|
||||
appOrigin: AppOrigin?,
|
||||
onOriginChecked: (origin: String) -> Unit,
|
||||
onOriginNotChecked: () -> Unit
|
||||
) {
|
||||
// Verify the app signature to retrieve the origin
|
||||
val appIdentifierStored = appOrigin?.appIdentifiers?.filter {
|
||||
it.id == this.id
|
||||
}
|
||||
if (appIdentifierStored?.any { it.signature == this.signature } == true) {
|
||||
onOriginChecked(this.buildAndroidOrigin())
|
||||
} else {
|
||||
onOriginNotChecked()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an Android Origin from a AppIdentifier
|
||||
*/
|
||||
fun AppIdentifier.buildAndroidOrigin(): String {
|
||||
return buildAndroidOrigin(this.id)
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an Android Origin from a package name.
|
||||
*/
|
||||
private fun buildAndroidOrigin(packageName: String?): String {
|
||||
if (packageName.isNullOrEmpty())
|
||||
throw SecurityException("Package name cannot be empty")
|
||||
val packageOrigin = "androidapp://${packageName}"
|
||||
Log.d(TAG, "Origin $packageOrigin retrieved from package name")
|
||||
return packageOrigin
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,11 +51,11 @@ import com.kunzisoft.keepass.credentialprovider.passkey.data.PublicKeyCredential
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.data.PublicKeyCredentialRequestOptions
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.data.PublicKeyCredentialUsageParameters
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.Base64Helper.Companion.b64Encode
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.OriginManager.Companion.checkInAppOrigin
|
||||
import com.kunzisoft.keepass.model.AppOrigin
|
||||
import com.kunzisoft.keepass.model.EntryInfo
|
||||
import com.kunzisoft.keepass.model.Passkey
|
||||
import com.kunzisoft.keepass.model.SearchInfo
|
||||
import com.kunzisoft.keepass.model.Verification
|
||||
import com.kunzisoft.keepass.utils.StringUtil.toHexString
|
||||
import com.kunzisoft.keepass.utils.getParcelableExtraCompat
|
||||
import com.kunzisoft.random.KeePassDXRandom
|
||||
@@ -364,7 +364,8 @@ object PasskeyHelper {
|
||||
OriginManager(
|
||||
providedClientDataHash = clientDataHash,
|
||||
callingAppInfo = callingAppInfo,
|
||||
assets = assetManager
|
||||
assets = assetManager,
|
||||
relyingParty = relyingParty
|
||||
).getOriginAtCreation(
|
||||
onOriginRetrieved = { appInfoToStore, clientDataHash ->
|
||||
passkeyCreated.invoke(
|
||||
@@ -441,7 +442,7 @@ object PasskeyHelper {
|
||||
suspend fun retrievePasskeyUsageRequestParameters(
|
||||
intent: Intent,
|
||||
assetManager: AssetManager,
|
||||
appOrigin: AppOrigin?,
|
||||
appOrigin: AppOrigin,
|
||||
result: (PublicKeyCredentialUsageParameters) -> Unit
|
||||
) {
|
||||
val getCredentialRequest = PendingIntentHandler.retrieveProviderGetCredentialRequest(intent)
|
||||
@@ -456,30 +457,32 @@ object PasskeyHelper {
|
||||
OriginManager(
|
||||
providedClientDataHash = clientDataHash,
|
||||
callingAppInfo = callingAppInfo,
|
||||
assets = assetManager
|
||||
assets = assetManager,
|
||||
relyingParty = requestOptions.rpId
|
||||
).getOriginAtUsage(
|
||||
appOrigin = appOrigin,
|
||||
onOriginRetrieved = { appIdentifier, clientDataHash ->
|
||||
onOriginRetrieved = { androidOrigin, webOrigin, clientDataHash ->
|
||||
result.invoke(
|
||||
PublicKeyCredentialUsageParameters(
|
||||
publicKeyCredentialRequestOptions = requestOptions,
|
||||
clientDataResponse = ClientDataDefinedResponse(clientDataHash),
|
||||
androidApp = appIdentifier,
|
||||
androidAppVerified = true
|
||||
androidOrigin = androidOrigin,
|
||||
webOrigin = webOrigin
|
||||
)
|
||||
)
|
||||
},
|
||||
onOriginCreated = { appIdentifier, origin, verified ->
|
||||
onOriginCreated = { androidOrigin, webOrigin ->
|
||||
// By default we crate an usage parameter with Android origin
|
||||
result.invoke(
|
||||
PublicKeyCredentialUsageParameters(
|
||||
publicKeyCredentialRequestOptions = requestOptions,
|
||||
clientDataResponse = ClientDataBuildResponse(
|
||||
type = ClientDataBuildResponse.Type.GET,
|
||||
challenge = requestOptions.challenge,
|
||||
origin = origin
|
||||
origin = androidOrigin.toAndroidOrigin()
|
||||
),
|
||||
androidApp = appIdentifier,
|
||||
androidAppVerified = verified
|
||||
androidOrigin = androidOrigin,
|
||||
webOrigin = webOrigin
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -518,30 +521,35 @@ object PasskeyHelper {
|
||||
* Verify that the application signature is contained in the [appOrigin]
|
||||
* or that the webDomain contains the origin
|
||||
*/
|
||||
fun getVerifiedClientDataResponse(
|
||||
fun getVerifiedGETClientDataResponse(
|
||||
usageParameters: PublicKeyCredentialUsageParameters,
|
||||
appOrigin: AppOrigin?,
|
||||
onOriginChecked: (clientDataResponse: ClientDataResponse) -> Unit,
|
||||
onOriginNotChecked: () -> Unit
|
||||
) {
|
||||
if (usageParameters.androidAppVerified) {
|
||||
onOriginChecked(usageParameters.clientDataResponse)
|
||||
appOrigin: AppOrigin
|
||||
): ClientDataResponse {
|
||||
val appToCheck = usageParameters.androidOrigin
|
||||
val webToCheck = usageParameters.webOrigin
|
||||
if (appToCheck.verification == Verification.AUTOMATICALLY_VERIFIED) {
|
||||
return usageParameters.clientDataResponse
|
||||
} else {
|
||||
usageParameters.androidApp.checkInAppOrigin(
|
||||
appOrigin = appOrigin,
|
||||
onOriginChecked = { origin ->
|
||||
// Origin checked by Android app signature
|
||||
onOriginChecked(
|
||||
ClientDataBuildResponse(
|
||||
type = ClientDataBuildResponse.Type.GET,
|
||||
challenge = usageParameters.publicKeyCredentialRequestOptions.challenge,
|
||||
origin = origin
|
||||
)
|
||||
if (appOrigin.containsVerifiedAndroidOrigin(appToCheck)) {
|
||||
if (webToCheck.verification.verified
|
||||
|| appOrigin.containsVerifiedWebOrigin(webToCheck)) {
|
||||
// Origin checked by URL
|
||||
return ClientDataBuildResponse(
|
||||
type = ClientDataBuildResponse.Type.GET,
|
||||
challenge = usageParameters.publicKeyCredentialRequestOptions.challenge,
|
||||
origin = webToCheck.toWebOrigin()
|
||||
)
|
||||
},
|
||||
onOriginNotChecked
|
||||
)
|
||||
}
|
||||
// Origin checked by Android app signature
|
||||
return ClientDataBuildResponse(
|
||||
type = ClientDataBuildResponse.Type.GET,
|
||||
challenge = usageParameters.publicKeyCredentialRequestOptions.challenge,
|
||||
origin = appOrigin.firstVerifiedWebOrigin()?.toWebOrigin()
|
||||
?: appToCheck.toAndroidOrigin()
|
||||
)
|
||||
} else {
|
||||
throw SecurityException("Wrong signature for ${appToCheck.packageName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user