fix: User Verified flag during registration #2283

This commit is contained in:
J-Jamet
2025-11-26 10:16:51 +01:00
parent f9051ce787
commit 609b536898
4 changed files with 32 additions and 10 deletions

View File

@@ -343,14 +343,17 @@ class PasskeyProviderService : CredentialProviderService() {
private fun MutableList<CreateEntry>.addPendingIntentCreationNewEntry(
accountName: String,
searchInfo: SearchInfo?
searchInfo: SearchInfo?,
userVerification: UserVerificationRequirement
) {
Log.d(TAG, "Add pending intent for registration in opened database to create new item")
// TODO add a setting to directly store in a specific group
PasskeyLauncherActivity.getPendingIntent(
context = applicationContext,
specialMode = SpecialMode.REGISTRATION,
searchInfo = searchInfo
searchInfo = searchInfo,
userVerification = userVerification,
userVerifiedWithAuth = false
)?.let { pendingIntent ->
this.add(
CreateEntry(
@@ -379,6 +382,7 @@ class PasskeyProviderService : CredentialProviderService() {
)
val relyingPartyId = publicKeyCredentialCreationOptions.relyingPartyEntity.id
val searchInfo = buildPasskeySearchInfo(relyingPartyId)
val userVerification = publicKeyCredentialCreationOptions.authenticatorSelection.userVerification
Log.d(TAG, "Build passkey search for relying party $relyingPartyId")
SearchHelper.checkAutoSearchInfo(
context = this,
@@ -389,7 +393,11 @@ class PasskeyProviderService : CredentialProviderService() {
throw RegisterInReadOnlyDatabaseException()
} else {
// To create a new entry
createEntries.addPendingIntentCreationNewEntry(accountName, searchInfo)
createEntries.addPendingIntentCreationNewEntry(
accountName = accountName,
searchInfo = searchInfo,
userVerification = userVerification
)
/* TODO Overwrite
// To select an existing entry and permit an overwrite
Log.w(TAG, "Passkey already registered")
@@ -420,7 +428,11 @@ class PasskeyProviderService : CredentialProviderService() {
if (database.isReadOnly) {
throw RegisterInReadOnlyDatabaseException()
} else {
createEntries.addPendingIntentCreationNewEntry(accountName, searchInfo)
createEntries.addPendingIntentCreationNewEntry(
accountName = accountName,
searchInfo = searchInfo,
userVerification = userVerification
)
}
callback(createEntries)
},
@@ -429,7 +441,8 @@ class PasskeyProviderService : CredentialProviderService() {
Log.d(TAG, "Add pending intent for passkey registration in closed database")
PasskeyLauncherActivity.getPendingIntent(
context = applicationContext,
specialMode = SpecialMode.REGISTRATION
specialMode = SpecialMode.REGISTRATION,
userVerifiedWithAuth = true
)?.let { pendingIntent ->
createEntries.add(
CreateEntry(

View File

@@ -148,11 +148,12 @@ data class PublicKeyCredentialDescriptor(
}
}
// https://www.w3.org/TR/webauthn-3/#dictdef-authenticatorselectioncriteria
data class AuthenticatorSelectionCriteria(
val authenticatorAttachment: String? = null,
val residentKey: ResidentKeyRequirement? = null,
val requireResidentKey: Boolean?,
val userVerification: UserVerificationRequirement? = UserVerificationRequirement.PREFERRED
val userVerification: UserVerificationRequirement = UserVerificationRequirement.PREFERRED
) {
companion object {
fun JSONObject.getAuthenticatorSelectionCriteria(
@@ -166,7 +167,9 @@ data class AuthenticatorSelectionCriteria(
ResidentKeyRequirement.fromString(authenticatorSelection.getString("residentKey"))
else null
val requireResidentKey = authenticatorSelection.optBoolean("requireResidentKey", false)
val userVerification = UserVerificationRequirement.fromString(authenticatorSelection.optString("userVerification", "preferred"))
val userVerification = UserVerificationRequirement
.fromString(authenticatorSelection.optString("userVerification", "preferred"))
?: UserVerificationRequirement.PREFERRED
// https://www.w3.org/TR/webauthn-3/#enumdef-residentkeyrequirement
if (residentKey == null) {
residentKey = if (requireResidentKey) {
@@ -195,7 +198,9 @@ enum class ResidentKeyRequirement(val value: String) {
}
companion object {
fun fromString(value: String): ResidentKeyRequirement? {
return ResidentKeyRequirement.entries.firstOrNull { it.value == value }
return ResidentKeyRequirement.entries.firstOrNull {
it.value.equals(other = value, ignoreCase = true)
}
}
}
}
@@ -210,7 +215,9 @@ enum class UserVerificationRequirement(val value: String) {
}
companion object {
fun fromString(value: String): UserVerificationRequirement? {
return UserVerificationRequirement.entries.firstOrNull { it.value == value }
return UserVerificationRequirement.entries.firstOrNull {
it.value.equals(other = value, ignoreCase = true)
}
}
}
}

View File

@@ -557,6 +557,7 @@ object PasskeyHelper {
*/
fun buildCreatePublicKeyCredentialResponse(
publicKeyCredentialCreationParameters: PublicKeyCredentialCreationParameters,
userVerified: Boolean,
backupEligibility: Boolean,
backupState: Boolean
): CreatePublicKeyCredentialResponse {
@@ -574,7 +575,7 @@ object PasskeyHelper {
keyTypeId = keyTypeId
) ?: mapOf<Int, Any>()),
userPresent = true,
userVerified = true,
userVerified = userVerified,
backupEligibility = backupEligibility,
backupState = backupState,
publicKeyTypeId = keyTypeId,

View File

@@ -525,6 +525,7 @@ class PasskeyLauncherViewModel(application: Application): CredentialLauncherView
intent = responseIntent,
response = buildCreatePublicKeyCredentialResponse(
publicKeyCredentialCreationParameters = it,
userVerified = mUserVerified,
backupEligibility = passkey?.backupEligibility
?: mBackupEligibility,
backupState = passkey?.backupState