mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
@@ -16,7 +16,25 @@
|
||||
|
||||
package com.kunzisoft.keepass.credentialprovider.passkey.data
|
||||
|
||||
data class PublicKeyCredentialRpEntity(val name: String, val id: String)
|
||||
import com.kunzisoft.encrypt.Base64Helper
|
||||
import org.json.JSONObject
|
||||
|
||||
data class PublicKeyCredentialRpEntity(
|
||||
val name: String,
|
||||
val id: String
|
||||
) {
|
||||
companion object {
|
||||
fun JSONObject.getPublicKeyCredentialRpEntity(
|
||||
parameterName: String
|
||||
): PublicKeyCredentialRpEntity {
|
||||
val rpJson = this.getJSONObject(parameterName)
|
||||
return PublicKeyCredentialRpEntity(
|
||||
rpJson.getString("name"),
|
||||
rpJson.getString("id")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class PublicKeyCredentialUserEntity(
|
||||
val name: String,
|
||||
@@ -42,9 +60,41 @@ data class PublicKeyCredentialUserEntity(
|
||||
result = 31 * result + displayName.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun JSONObject.getPublicKeyCredentialUserEntity(
|
||||
parameterName: String
|
||||
): PublicKeyCredentialUserEntity {
|
||||
val rpUser = this.getJSONObject(parameterName)
|
||||
return PublicKeyCredentialUserEntity(
|
||||
rpUser.getString("name"),
|
||||
Base64Helper.b64Decode(rpUser.getString("id")),
|
||||
rpUser.getString("displayName")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class PublicKeyCredentialParameters(val type: String, val alg: Long)
|
||||
data class PublicKeyCredentialParameters(
|
||||
val type: String,
|
||||
val alg: Long
|
||||
) {
|
||||
companion object {
|
||||
fun JSONObject.getPublicKeyCredentialParametersList(
|
||||
parameterName: String
|
||||
): List<PublicKeyCredentialParameters> {
|
||||
val pubKeyCredParamsJson = this.getJSONArray(parameterName)
|
||||
val pubKeyCredParamsTmp: MutableList<PublicKeyCredentialParameters> = mutableListOf()
|
||||
for (i in 0 until pubKeyCredParamsJson.length()) {
|
||||
val e = pubKeyCredParamsJson.getJSONObject(i)
|
||||
pubKeyCredParamsTmp.add(
|
||||
PublicKeyCredentialParameters(e.getString("type"), e.getLong("alg"))
|
||||
)
|
||||
}
|
||||
return pubKeyCredParamsTmp.toList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class PublicKeyCredentialDescriptor(
|
||||
val type: String,
|
||||
@@ -70,11 +120,97 @@ data class PublicKeyCredentialDescriptor(
|
||||
result = 31 * result + transports.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun JSONObject.getPublicKeyCredentialDescriptorList(
|
||||
parameterName: String
|
||||
): List<PublicKeyCredentialDescriptor> {
|
||||
val credentialsJson = this.getJSONArray(parameterName)
|
||||
val credentialsTmp: MutableList<PublicKeyCredentialDescriptor> = mutableListOf()
|
||||
for (i in 0 until credentialsJson.length()) {
|
||||
val credentialJson = credentialsJson.getJSONObject(i)
|
||||
|
||||
val transports: MutableList<String> = mutableListOf()
|
||||
val transportsJson = credentialJson.getJSONArray("transports")
|
||||
for (j in 0 until transportsJson.length()) {
|
||||
transports.add(transportsJson.getString(j))
|
||||
}
|
||||
credentialsTmp.add(
|
||||
PublicKeyCredentialDescriptor(
|
||||
type = credentialJson.getString("type"),
|
||||
id = Base64Helper.b64Decode(credentialJson.getString("id")),
|
||||
transports = transports
|
||||
)
|
||||
)
|
||||
}
|
||||
return credentialsTmp.toList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class AuthenticatorSelectionCriteria(
|
||||
val authenticatorAttachment: String,
|
||||
val residentKey: String,
|
||||
val requireResidentKey: Boolean = false,
|
||||
val userVerification: String = "preferred"
|
||||
)
|
||||
val authenticatorAttachment: String? = null,
|
||||
val residentKey: ResidentKeyRequirement? = null,
|
||||
val requireResidentKey: Boolean?,
|
||||
val userVerification: UserVerificationRequirement? = UserVerificationRequirement.PREFERRED
|
||||
) {
|
||||
companion object {
|
||||
fun JSONObject.getAuthenticatorSelectionCriteria(
|
||||
parameterName: String
|
||||
): AuthenticatorSelectionCriteria {
|
||||
val authenticatorSelection = this.optJSONObject(parameterName)
|
||||
?: return AuthenticatorSelectionCriteria(requireResidentKey = null)
|
||||
val authenticatorAttachment = if (!authenticatorSelection.isNull("authenticatorAttachment"))
|
||||
authenticatorSelection.getString("authenticatorAttachment") else null
|
||||
var residentKey = if (!authenticatorSelection.isNull("residentKey"))
|
||||
ResidentKeyRequirement.fromString(authenticatorSelection.getString("residentKey"))
|
||||
else null
|
||||
val requireResidentKey = authenticatorSelection.optBoolean("requireResidentKey", false)
|
||||
val userVerification = UserVerificationRequirement.fromString(authenticatorSelection.optString("userVerification", "preferred"))
|
||||
// https://www.w3.org/TR/webauthn-3/#enumdef-residentkeyrequirement
|
||||
if (residentKey == null) {
|
||||
residentKey = if (requireResidentKey) {
|
||||
ResidentKeyRequirement.REQUIRED
|
||||
} else {
|
||||
ResidentKeyRequirement.DISCOURAGED
|
||||
}
|
||||
}
|
||||
return AuthenticatorSelectionCriteria(
|
||||
authenticatorAttachment = authenticatorAttachment,
|
||||
residentKey = residentKey,
|
||||
requireResidentKey = requireResidentKey,
|
||||
userVerification = userVerification
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/webauthn-3/#enumdef-residentkeyrequirement
|
||||
enum class ResidentKeyRequirement(val value: String) {
|
||||
DISCOURAGED("discouraged"),
|
||||
PREFERRED("preferred"),
|
||||
REQUIRED("required");
|
||||
override fun toString(): String {
|
||||
return value
|
||||
}
|
||||
companion object {
|
||||
fun fromString(value: String): ResidentKeyRequirement? {
|
||||
return ResidentKeyRequirement.entries.firstOrNull { it.value == value }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/webauthn-3/#enumdef-userverificationrequirement
|
||||
enum class UserVerificationRequirement(val value: String) {
|
||||
REQUIRED("required"),
|
||||
PREFERRED("preferred"),
|
||||
DISCOURAGED("discouraged");
|
||||
override fun toString(): String {
|
||||
return value
|
||||
}
|
||||
companion object {
|
||||
fun fromString(value: String): UserVerificationRequirement? {
|
||||
return UserVerificationRequirement.entries.firstOrNull { it.value == value }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,51 +20,42 @@
|
||||
package com.kunzisoft.keepass.credentialprovider.passkey.data
|
||||
|
||||
import com.kunzisoft.encrypt.Base64Helper
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.data.AuthenticatorSelectionCriteria.Companion.getAuthenticatorSelectionCriteria
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.data.PublicKeyCredentialDescriptor.Companion.getPublicKeyCredentialDescriptorList
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.data.PublicKeyCredentialParameters.Companion.getPublicKeyCredentialParametersList
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.data.PublicKeyCredentialRpEntity.Companion.getPublicKeyCredentialRpEntity
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.data.PublicKeyCredentialUserEntity.Companion.getPublicKeyCredentialUserEntity
|
||||
import org.json.JSONObject
|
||||
|
||||
class PublicKeyCredentialCreationOptions(
|
||||
requestJson: String,
|
||||
var clientDataHash: ByteArray?
|
||||
) {
|
||||
val json: JSONObject = JSONObject(requestJson)
|
||||
private val json: JSONObject = JSONObject(requestJson)
|
||||
|
||||
val relyingPartyEntity: PublicKeyCredentialRpEntity
|
||||
val userEntity: PublicKeyCredentialUserEntity
|
||||
val challenge: ByteArray
|
||||
val pubKeyCredParams: List<PublicKeyCredentialParameters>
|
||||
val relyingPartyEntity: PublicKeyCredentialRpEntity =
|
||||
json.getPublicKeyCredentialRpEntity("rp")
|
||||
|
||||
var timeout: Long
|
||||
var excludeCredentials: List<PublicKeyCredentialDescriptor>
|
||||
var authenticatorSelection: AuthenticatorSelectionCriteria
|
||||
var attestation: String
|
||||
val userEntity: PublicKeyCredentialUserEntity =
|
||||
json.getPublicKeyCredentialUserEntity("user")
|
||||
|
||||
init {
|
||||
val rpJson = json.getJSONObject("rp")
|
||||
relyingPartyEntity = PublicKeyCredentialRpEntity(rpJson.getString("name"), rpJson.getString("id"))
|
||||
val rpUser = json.getJSONObject("user")
|
||||
userEntity =
|
||||
PublicKeyCredentialUserEntity(
|
||||
rpUser.getString("name"),
|
||||
Base64Helper.b64Decode(rpUser.getString("id")),
|
||||
rpUser.getString("displayName")
|
||||
)
|
||||
challenge = Base64Helper.b64Decode(json.getString("challenge"))
|
||||
val pubKeyCredParamsJson = json.getJSONArray("pubKeyCredParams")
|
||||
val pubKeyCredParamsTmp: MutableList<PublicKeyCredentialParameters> = mutableListOf()
|
||||
for (i in 0 until pubKeyCredParamsJson.length()) {
|
||||
val e = pubKeyCredParamsJson.getJSONObject(i)
|
||||
pubKeyCredParamsTmp.add(
|
||||
PublicKeyCredentialParameters(e.getString("type"), e.getLong("alg"))
|
||||
)
|
||||
}
|
||||
pubKeyCredParams = pubKeyCredParamsTmp.toList()
|
||||
val challenge: ByteArray =
|
||||
Base64Helper.b64Decode(json.getString("challenge"))
|
||||
|
||||
timeout = json.optLong("timeout", 0)
|
||||
// TODO: Fix excludeCredentials and authenticatorSelection
|
||||
excludeCredentials = emptyList()
|
||||
authenticatorSelection = AuthenticatorSelectionCriteria("platform", "required")
|
||||
attestation = json.optString("attestation", "none")
|
||||
}
|
||||
val pubKeyCredParams: List<PublicKeyCredentialParameters> =
|
||||
json.getPublicKeyCredentialParametersList("pubKeyCredParams")
|
||||
|
||||
var timeout: Long =
|
||||
json.optLong("timeout", 0)
|
||||
|
||||
var excludeCredentials: List<PublicKeyCredentialDescriptor> =
|
||||
json.getPublicKeyCredentialDescriptorList("excludeCredentials")
|
||||
|
||||
var authenticatorSelection: AuthenticatorSelectionCriteria =
|
||||
json.getAuthenticatorSelectionCriteria("authenticatorSelection")
|
||||
|
||||
var attestation: String =
|
||||
json.optString("attestation", "none")
|
||||
|
||||
companion object {
|
||||
private val TAG = PublicKeyCredentialCreationOptions::class.simpleName
|
||||
|
||||
@@ -20,35 +20,33 @@
|
||||
package com.kunzisoft.keepass.credentialprovider.passkey.data
|
||||
|
||||
import com.kunzisoft.encrypt.Base64Helper
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.data.PublicKeyCredentialDescriptor.Companion.getPublicKeyCredentialDescriptorList
|
||||
import org.json.JSONObject
|
||||
|
||||
// https://www.w3.org/TR/webauthn-3/#enumdef-residentkeyrequirement
|
||||
class PublicKeyCredentialRequestOptions(requestJson: String) {
|
||||
private val json: JSONObject = JSONObject(requestJson)
|
||||
val challenge: ByteArray = Base64Helper.b64Decode(json.getString("challenge"))
|
||||
val timeout: Long = json.optLong("timeout", 0)
|
||||
val rpId: String = json.optString("rpId", "")
|
||||
val allowCredentials: List<PublicKeyCredentialDescriptor>
|
||||
val userVerification: String = json.optString("userVerification", "preferred")
|
||||
|
||||
init {
|
||||
val allowCredentialsJson = json.getJSONArray("allowCredentials")
|
||||
val allowCredentialsTmp: MutableList<PublicKeyCredentialDescriptor> = mutableListOf()
|
||||
for (i in 0 until allowCredentialsJson.length()) {
|
||||
val allowCredentialJson = allowCredentialsJson.getJSONObject(i)
|
||||
val challenge: ByteArray =
|
||||
Base64Helper.b64Decode(json.getString("challenge"))
|
||||
|
||||
val transports: MutableList<String> = mutableListOf()
|
||||
val transportsJson = allowCredentialJson.getJSONArray("transports")
|
||||
for (j in 0 until transportsJson.length()) {
|
||||
transports.add(transportsJson.getString(j))
|
||||
}
|
||||
allowCredentialsTmp.add(
|
||||
PublicKeyCredentialDescriptor(
|
||||
type = allowCredentialJson.getString("type"),
|
||||
id = Base64Helper.b64Decode(allowCredentialJson.getString("id")),
|
||||
transports = transports
|
||||
)
|
||||
)
|
||||
}
|
||||
allowCredentials = allowCredentialsTmp.toList()
|
||||
}
|
||||
val timeout: Long =
|
||||
json.optLong("timeout", 0)
|
||||
|
||||
val rpId: String =
|
||||
json.optString("rpId", "")
|
||||
|
||||
val allowCredentials: List<PublicKeyCredentialDescriptor> =
|
||||
json.getPublicKeyCredentialDescriptorList("allowCredentials")
|
||||
|
||||
val userVerification: UserVerificationRequirement =
|
||||
UserVerificationRequirement.fromString(
|
||||
json.optString("userVerification", "preferred"))
|
||||
?: UserVerificationRequirement.PREFERRED
|
||||
|
||||
// TODO Hints
|
||||
val hints: List<String> = listOf()
|
||||
|
||||
// TODO Extensions
|
||||
// val extensions: AuthenticationExtensionsClientInputs
|
||||
}
|
||||
Reference in New Issue
Block a user