Android implementation

This commit is contained in:
Adam Velebil 2024-08-12 09:27:46 +02:00
parent 5d7a36ee8a
commit ba85a257d4
No known key found for this signature in database
GPG Key ID: C9B1E4A3CBBD2E10
4 changed files with 70 additions and 4 deletions

View File

@ -26,6 +26,7 @@ enum class FidoActionDescription(private val value: Int) {
DeleteFingerprint(4),
RenameFingerprint(5),
RegisterFingerprint(6),
EnableEnterpriseAttestation(7),
ActionFailure(7);
val id: Int

View File

@ -42,6 +42,7 @@ import com.yubico.yubikit.core.smartcard.SmartCardConnection
import com.yubico.yubikit.core.util.Result
import com.yubico.yubikit.fido.ctap.BioEnrollment
import com.yubico.yubikit.fido.ctap.ClientPin
import com.yubico.yubikit.fido.ctap.Config
import com.yubico.yubikit.fido.ctap.CredentialManagement
import com.yubico.yubikit.fido.ctap.Ctap2Session.InfoData
import com.yubico.yubikit.fido.ctap.FingerprintBioEnrollment
@ -159,6 +160,8 @@ class FidoManager(
"cancelRegisterFingerprint" -> cancelRegisterFingerprint()
"enableEnterpriseAttestation" -> enableEnterpriseAttestation()
else -> throw NotImplementedError()
}
}
@ -249,6 +252,11 @@ class FidoManager(
ClientPin.PIN_PERMISSION_BE else 0
}
private fun getPinPermissionsACFG(fidoSession: YubiKitFidoSession): Int {
return if(Config.isSupported(fidoSession.cachedInfo))
ClientPin.PIN_PERMISSION_ACFG else 0
}
private fun unlockSession(
fidoSession: YubiKitFidoSession,
clientPin: ClientPin,
@ -603,6 +611,44 @@ class FidoManager(
).toString()
}
private suspend fun enableEnterpriseAttestation(): String =
connectionHelper.useSession(FidoActionDescription.EnableEnterpriseAttestation) { fidoSession ->
val uvAuthProtocol = getPreferredPinUvAuthProtocol(fidoSession.cachedInfo)
val clientPin = ClientPin(fidoSession, uvAuthProtocol)
val token = if (pinStore.hasPin()) {
clientPin.getPinToken(
pinStore.getPin(),
getPinPermissionsACFG(fidoSession),
null
)
} else null
val config = Config(fidoSession, uvAuthProtocol, token)
try {
config.enableEnterpriseAttestation()
fidoViewModel.setSessionState(
Session(
fidoSession.info,
pinStore.hasPin(),
pinRetries
)
)
return@useSession JSONObject(
mapOf(
"success" to true,
)
).toString()
} catch (e: Exception) {
logger.error("Failed to enable enterprise attestation. ", e)
return@useSession JSONObject(
mapOf(
"success" to false,
)
).toString()
}
}
override fun onDisconnected() {
if (!resetHelper.inProgress) {

View File

@ -29,7 +29,8 @@ data class Options(
val credMgmt: Boolean,
val credentialMgmtPreview: Boolean,
val bioEnroll: Boolean?,
val alwaysUv: Boolean
val alwaysUv: Boolean,
val ep: Boolean?,
) {
constructor(infoData: InfoData) : this(
infoData.getOptionsBoolean("clientPin") == true,
@ -37,6 +38,7 @@ data class Options(
infoData.getOptionsBoolean("credentialMgmtPreview") == true,
infoData.getOptionsBoolean("bioEnroll"),
infoData.getOptionsBoolean("alwaysUv") == true,
infoData.getOptionsBoolean("ep"),
)
companion object {

View File

@ -163,9 +163,26 @@ class _FidoStateNotifier extends FidoStateNotifier {
}
@override
Future<void> enableEnterpriseAttestation() {
// TODO: implement enableEnterpriseAttestation
throw UnimplementedError();
Future<void> enableEnterpriseAttestation() async {
try {
final response = jsonDecode(await _methods.invokeMethod(
'enableEnterpriseAttestation',
));
if (response['success'] == true) {
_log.debug('Enterprise attestation enabled');
}
} on PlatformException catch (pe) {
var decodedException = pe.decode();
if (decodedException is CancellationException) {
_log.debug('User cancelled unlock FIDO operation');
throw decodedException;
}
_log.debug(
'Platform exception during enable enterprise attestation: $pe');
rethrow;
}
}
}