@tokamakdev/plugin-secure-storage 0.1.0-beta.106 → 0.1.0-beta.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/android/Bindings.kt +356 -0
- package/android/SecureStoragePlugin.kt +27 -21
- package/android/bindings.ts +1166 -0
- package/apple/SecureStoragePlugin.swift +27 -16
- package/package.json +4 -3
- package/src/index.ts +4 -4
- package/tokamak-plugin.json +45 -4
package/README.md
CHANGED
|
@@ -8,8 +8,12 @@ Add it to your project's dependencies:
|
|
|
8
8
|
npm install @tokamakdev/plugin-secure-storage
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
Pages import the generated `/client` SDK. In `src/tokamak.ts`, import the
|
|
12
|
+
package root and call its factory with the handler's `ctx`. The main worker
|
|
13
|
+
uses its generated `env.TOKAMAK_SECURE_STORAGE` service binding when present.
|
|
14
|
+
|
|
11
15
|
```ts
|
|
12
|
-
import
|
|
16
|
+
import secureStorage from "@tokamakdev/plugin-secure-storage/client";
|
|
13
17
|
|
|
14
18
|
const options = {
|
|
15
19
|
// Required: "whenUnlocked" or "afterFirstUnlock".
|
|
@@ -69,6 +73,14 @@ authentication an existing value was saved with before replacing it, as it does
|
|
|
69
73
|
for a read: `replace` and `set` then show their `prompt` and need the app on
|
|
70
74
|
screen. Android replaces values without asking.
|
|
71
75
|
|
|
76
|
+
## Platform bindings
|
|
77
|
+
|
|
78
|
+
`@tokamakdev/plugin-secure-storage/android` is Android's
|
|
79
|
+
`android.security.keystore` package with `KeyStore`, `Cipher` and
|
|
80
|
+
`KeyGenerator`, for Worker code that needs what this API does not offer. The
|
|
81
|
+
Keychain's calls take dictionaries and pointers that bindings cannot express,
|
|
82
|
+
so Apple platforms have no bindings here.
|
|
83
|
+
|
|
72
84
|
## Errors
|
|
73
85
|
|
|
74
86
|
| Name | When |
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
// Generated by `tok bindings` from the Android 35 SDK: android.security.keystore, java.security.KeyStore, javax.crypto.Cipher, javax.crypto.KeyGenerator. Do not edit.
|
|
2
|
+
@file:Suppress("DEPRECATION", "OVERRIDE_DEPRECATION", "UNCHECKED_CAST")
|
|
3
|
+
@file:SuppressLint("MissingPermission")
|
|
4
|
+
|
|
5
|
+
package com.tokamak.bindings.secure_storage
|
|
6
|
+
|
|
7
|
+
import android.annotation.SuppressLint
|
|
8
|
+
import android.os.Build
|
|
9
|
+
import com.tokamak.runtime.TokamakBinding
|
|
10
|
+
import com.tokamak.runtime.TokamakHost
|
|
11
|
+
import com.tokamak.runtime.TokamakPlugin
|
|
12
|
+
import com.tokamak.runtime.TokamakPluginBytesReply
|
|
13
|
+
import com.tokamak.runtime.TokamakPluginError
|
|
14
|
+
|
|
15
|
+
class Bindings(private val host: TokamakHost) : TokamakPlugin {
|
|
16
|
+
override val id = "secure-storage/android"
|
|
17
|
+
|
|
18
|
+
override fun callBytes(method: String, payload: ByteArray, reply: TokamakPluginBytesReply): (() -> Unit)? {
|
|
19
|
+
val b = TokamakBinding(payload, host.resources, reply)
|
|
20
|
+
return when (method.substringBefore('#')) {
|
|
21
|
+
"BackendBusyException" -> callBackendBusyException(method, b)
|
|
22
|
+
"KeyExpiredException" -> callKeyExpiredException(method, b)
|
|
23
|
+
"KeyGenParameterSpec" -> callKeyGenParameterSpec(method, b)
|
|
24
|
+
"KeyGenParameterSpec.Builder" -> callKeyGenParameterSpec_Builder(method, b)
|
|
25
|
+
"KeyInfo" -> callKeyInfo(method, b)
|
|
26
|
+
"KeyNotYetValidException" -> callKeyNotYetValidException(method, b)
|
|
27
|
+
"KeyPermanentlyInvalidatedException" -> callKeyPermanentlyInvalidatedException(method, b)
|
|
28
|
+
"KeyProtection" -> callKeyProtection(method, b)
|
|
29
|
+
"KeyProtection.Builder" -> callKeyProtection_Builder(method, b)
|
|
30
|
+
"SecureKeyImportUnavailableException" -> callSecureKeyImportUnavailableException(method, b)
|
|
31
|
+
"StrongBoxUnavailableException" -> callStrongBoxUnavailableException(method, b)
|
|
32
|
+
"UserNotAuthenticatedException" -> callUserNotAuthenticatedException(method, b)
|
|
33
|
+
"UserPresenceUnavailableException" -> callUserPresenceUnavailableException(method, b)
|
|
34
|
+
"WrappedKeyEntry" -> callWrappedKeyEntry(method, b)
|
|
35
|
+
"KeyStore" -> callKeyStore(method, b)
|
|
36
|
+
"KeyStore.Builder" -> callKeyStore_Builder(method, b)
|
|
37
|
+
"KeyStore.Entry" -> callKeyStore_Entry(method, b)
|
|
38
|
+
"KeyStore.Entry.Attribute" -> callKeyStore_Entry_Attribute(method, b)
|
|
39
|
+
"KeyStore.LoadStoreParameter" -> callKeyStore_LoadStoreParameter(method, b)
|
|
40
|
+
"KeyStore.PasswordProtection" -> callKeyStore_PasswordProtection(method, b)
|
|
41
|
+
"KeyStore.PrivateKeyEntry" -> callKeyStore_PrivateKeyEntry(method, b)
|
|
42
|
+
"KeyStore.SecretKeyEntry" -> callKeyStore_SecretKeyEntry(method, b)
|
|
43
|
+
"KeyStore.TrustedCertificateEntry" -> callKeyStore_TrustedCertificateEntry(method, b)
|
|
44
|
+
"Cipher" -> callCipher(method, b)
|
|
45
|
+
"KeyGenerator" -> callKeyGenerator(method, b)
|
|
46
|
+
else -> b.unsupported(method)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
override fun subscribeBytes(method: String, payload: ByteArray, reply: TokamakPluginBytesReply): () -> Unit {
|
|
51
|
+
val b = TokamakBinding(payload, host.resources, reply)
|
|
52
|
+
return when (method) {
|
|
53
|
+
else -> throw TokamakPluginError.notSupported("$method is not supported")
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private fun callBackendBusyException(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
58
|
+
when (method) {
|
|
59
|
+
"BackendBusyException#<init>(J)V" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(android.security.keystore.BackendBusyException(b.long(b[0]))) }
|
|
60
|
+
"BackendBusyException#<init>(JLjava/lang/String;)V" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(android.security.keystore.BackendBusyException(b.long(b[0]), b.string(b[1]))) }
|
|
61
|
+
"BackendBusyException#getBackOffHintMillis()J" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.BackendBusyException::class.java).getBackOffHintMillis()) }
|
|
62
|
+
else -> b.unsupported(method)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private fun callKeyExpiredException(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
66
|
+
when (method) {
|
|
67
|
+
"KeyExpiredException#<init>()V" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(android.security.keystore.KeyExpiredException()) }
|
|
68
|
+
"KeyExpiredException#<init>(Ljava/lang/String;)V" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(android.security.keystore.KeyExpiredException(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
69
|
+
else -> b.unsupported(method)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private fun callKeyGenParameterSpec(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
73
|
+
when (method) {
|
|
74
|
+
"KeyGenParameterSpec#getKeystoreAlias()Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getKeystoreAlias()) }
|
|
75
|
+
"KeyGenParameterSpec#getKeySize()I" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getKeySize()) }
|
|
76
|
+
"KeyGenParameterSpec#getPurposes()I" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getPurposes()) }
|
|
77
|
+
"KeyGenParameterSpec#getDigests()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getDigests()) }
|
|
78
|
+
"KeyGenParameterSpec#isDigestsSpecified()Z" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isDigestsSpecified()) }
|
|
79
|
+
"KeyGenParameterSpec#getEncryptionPaddings()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getEncryptionPaddings()) }
|
|
80
|
+
"KeyGenParameterSpec#getSignaturePaddings()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getSignaturePaddings()) }
|
|
81
|
+
"KeyGenParameterSpec#getBlockModes()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getBlockModes()) }
|
|
82
|
+
"KeyGenParameterSpec#isRandomizedEncryptionRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isRandomizedEncryptionRequired()) }
|
|
83
|
+
"KeyGenParameterSpec#isUserAuthenticationRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isUserAuthenticationRequired()) }
|
|
84
|
+
"KeyGenParameterSpec#getUserAuthenticationValidityDurationSeconds()I" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getUserAuthenticationValidityDurationSeconds()) }
|
|
85
|
+
"KeyGenParameterSpec#getAttestationChallenge()[B" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getAttestationChallenge()) }
|
|
86
|
+
"KeyGenParameterSpec#isUserAuthenticationValidWhileOnBody()Z" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isUserAuthenticationValidWhileOnBody()) }
|
|
87
|
+
"KeyGenParameterSpec#isInvalidatedByBiometricEnrollment()Z" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isInvalidatedByBiometricEnrollment()) }
|
|
88
|
+
"KeyGenParameterSpec#isUserConfirmationRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isUserConfirmationRequired()) }
|
|
89
|
+
"KeyGenParameterSpec#isUserPresenceRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isUserPresenceRequired()) }
|
|
90
|
+
"KeyGenParameterSpec#isStrongBoxBacked()Z" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isStrongBoxBacked()) }
|
|
91
|
+
"KeyGenParameterSpec#isUnlockedDeviceRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isUnlockedDeviceRequired()) }
|
|
92
|
+
"KeyGenParameterSpec#getUserAuthenticationType()I" -> b.run { if (Build.VERSION.SDK_INT < 30) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getUserAuthenticationType()) }
|
|
93
|
+
"KeyGenParameterSpec#isDevicePropertiesAttestationIncluded()Z" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isDevicePropertiesAttestationIncluded()) }
|
|
94
|
+
"KeyGenParameterSpec#getMaxUsageCount()I" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getMaxUsageCount()) }
|
|
95
|
+
"KeyGenParameterSpec#getAttestKeyAlias()Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getAttestKeyAlias()) }
|
|
96
|
+
"KeyGenParameterSpec#getMgf1Digests()Ljava/util/Set;" -> b.run { if (Build.VERSION.SDK_INT < 35) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).getMgf1Digests()) }
|
|
97
|
+
"KeyGenParameterSpec#isMgf1DigestsSpecified()Z" -> b.run { if (Build.VERSION.SDK_INT < 35) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec::class.java).isMgf1DigestsSpecified()) }
|
|
98
|
+
else -> b.unsupported(method)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private fun callKeyGenParameterSpec_Builder(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
102
|
+
when (method) {
|
|
103
|
+
"KeyGenParameterSpec.Builder#<init>(Ljava/lang/String;I)V" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(android.security.keystore.KeyGenParameterSpec.Builder(b.string(b[0]), b.int(b[1]))) }
|
|
104
|
+
"KeyGenParameterSpec.Builder#setKeySize(I)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setKeySize(b.int(b[0]))) }
|
|
105
|
+
"KeyGenParameterSpec.Builder#setDigests([Ljava/lang/String;)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setDigests(*b.list(b[0]) { x1 -> b.optional(x1) { x2 -> b.string(x2) } }.toTypedArray())) }
|
|
106
|
+
"KeyGenParameterSpec.Builder#setEncryptionPaddings([Ljava/lang/String;)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setEncryptionPaddings(*b.list(b[0]) { x1 -> b.optional(x1) { x2 -> b.string(x2) } }.toTypedArray())) }
|
|
107
|
+
"KeyGenParameterSpec.Builder#setSignaturePaddings([Ljava/lang/String;)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setSignaturePaddings(*b.list(b[0]) { x1 -> b.optional(x1) { x2 -> b.string(x2) } }.toTypedArray())) }
|
|
108
|
+
"KeyGenParameterSpec.Builder#setBlockModes([Ljava/lang/String;)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setBlockModes(*b.list(b[0]) { x1 -> b.optional(x1) { x2 -> b.string(x2) } }.toTypedArray())) }
|
|
109
|
+
"KeyGenParameterSpec.Builder#setRandomizedEncryptionRequired(Z)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setRandomizedEncryptionRequired(b.boolean(b[0]))) }
|
|
110
|
+
"KeyGenParameterSpec.Builder#setUserAuthenticationRequired(Z)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setUserAuthenticationRequired(b.boolean(b[0]))) }
|
|
111
|
+
"KeyGenParameterSpec.Builder#setUserAuthenticationValidityDurationSeconds(I)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setUserAuthenticationValidityDurationSeconds(b.int(b[0]))) }
|
|
112
|
+
"KeyGenParameterSpec.Builder#build()Landroid/security/keystore/KeyGenParameterSpec;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).build()) }
|
|
113
|
+
"KeyGenParameterSpec.Builder#setAttestationChallenge([B)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setAttestationChallenge(b.optional(b[0]) { x1 -> b.bytes(x1) })) }
|
|
114
|
+
"KeyGenParameterSpec.Builder#setUserAuthenticationValidWhileOnBody(Z)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setUserAuthenticationValidWhileOnBody(b.boolean(b[0]))) }
|
|
115
|
+
"KeyGenParameterSpec.Builder#setInvalidatedByBiometricEnrollment(Z)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setInvalidatedByBiometricEnrollment(b.boolean(b[0]))) }
|
|
116
|
+
"KeyGenParameterSpec.Builder#setUserConfirmationRequired(Z)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setUserConfirmationRequired(b.boolean(b[0]))) }
|
|
117
|
+
"KeyGenParameterSpec.Builder#setUserPresenceRequired(Z)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setUserPresenceRequired(b.boolean(b[0]))) }
|
|
118
|
+
"KeyGenParameterSpec.Builder#setIsStrongBoxBacked(Z)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setIsStrongBoxBacked(b.boolean(b[0]))) }
|
|
119
|
+
"KeyGenParameterSpec.Builder#setUnlockedDeviceRequired(Z)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setUnlockedDeviceRequired(b.boolean(b[0]))) }
|
|
120
|
+
"KeyGenParameterSpec.Builder#setUserAuthenticationParameters(II)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 30) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setUserAuthenticationParameters(b.int(b[0]), b.int(b[1]))) }
|
|
121
|
+
"KeyGenParameterSpec.Builder#setDevicePropertiesAttestationIncluded(Z)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setDevicePropertiesAttestationIncluded(b.boolean(b[0]))) }
|
|
122
|
+
"KeyGenParameterSpec.Builder#setMaxUsageCount(I)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setMaxUsageCount(b.int(b[0]))) }
|
|
123
|
+
"KeyGenParameterSpec.Builder#setAttestKeyAlias(Ljava/lang/String;)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setAttestKeyAlias(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
124
|
+
"KeyGenParameterSpec.Builder#setMgf1Digests([Ljava/lang/String;)Landroid/security/keystore/KeyGenParameterSpec\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 35) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyGenParameterSpec.Builder::class.java).setMgf1Digests(*b.list(b[0]) { x1 -> b.string(x1) }.toTypedArray())) }
|
|
125
|
+
else -> b.unsupported(method)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private fun callKeyInfo(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
129
|
+
when (method) {
|
|
130
|
+
"KeyInfo#getKeystoreAlias()Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getKeystoreAlias()) }
|
|
131
|
+
"KeyInfo#isInsideSecureHardware()Z" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).isInsideSecureHardware()) }
|
|
132
|
+
"KeyInfo#getOrigin()I" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getOrigin()) }
|
|
133
|
+
"KeyInfo#getKeySize()I" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getKeySize()) }
|
|
134
|
+
"KeyInfo#getPurposes()I" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getPurposes()) }
|
|
135
|
+
"KeyInfo#getBlockModes()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getBlockModes()) }
|
|
136
|
+
"KeyInfo#getEncryptionPaddings()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getEncryptionPaddings()) }
|
|
137
|
+
"KeyInfo#getSignaturePaddings()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getSignaturePaddings()) }
|
|
138
|
+
"KeyInfo#getDigests()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getDigests()) }
|
|
139
|
+
"KeyInfo#isUserAuthenticationRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).isUserAuthenticationRequired()) }
|
|
140
|
+
"KeyInfo#getUserAuthenticationValidityDurationSeconds()I" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getUserAuthenticationValidityDurationSeconds()) }
|
|
141
|
+
"KeyInfo#isUserAuthenticationRequirementEnforcedBySecureHardware()Z" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).isUserAuthenticationRequirementEnforcedBySecureHardware()) }
|
|
142
|
+
"KeyInfo#isUserAuthenticationValidWhileOnBody()Z" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).isUserAuthenticationValidWhileOnBody()) }
|
|
143
|
+
"KeyInfo#isInvalidatedByBiometricEnrollment()Z" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).isInvalidatedByBiometricEnrollment()) }
|
|
144
|
+
"KeyInfo#isUserConfirmationRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).isUserConfirmationRequired()) }
|
|
145
|
+
"KeyInfo#isTrustedUserPresenceRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).isTrustedUserPresenceRequired()) }
|
|
146
|
+
"KeyInfo#getUserAuthenticationType()I" -> b.run { if (Build.VERSION.SDK_INT < 30) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getUserAuthenticationType()) }
|
|
147
|
+
"KeyInfo#getSecurityLevel()I" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getSecurityLevel()) }
|
|
148
|
+
"KeyInfo#getRemainingUsageCount()I" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyInfo::class.java).getRemainingUsageCount()) }
|
|
149
|
+
else -> b.unsupported(method)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private fun callKeyNotYetValidException(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
153
|
+
when (method) {
|
|
154
|
+
"KeyNotYetValidException#<init>()V" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(android.security.keystore.KeyNotYetValidException()) }
|
|
155
|
+
"KeyNotYetValidException#<init>(Ljava/lang/String;)V" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(android.security.keystore.KeyNotYetValidException(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
156
|
+
else -> b.unsupported(method)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
private fun callKeyPermanentlyInvalidatedException(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
160
|
+
when (method) {
|
|
161
|
+
"KeyPermanentlyInvalidatedException#<init>()V" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(android.security.keystore.KeyPermanentlyInvalidatedException()) }
|
|
162
|
+
"KeyPermanentlyInvalidatedException#<init>(Ljava/lang/String;)V" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(android.security.keystore.KeyPermanentlyInvalidatedException(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
163
|
+
else -> b.unsupported(method)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private fun callKeyProtection(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
167
|
+
when (method) {
|
|
168
|
+
"KeyProtection#getPurposes()I" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).getPurposes()) }
|
|
169
|
+
"KeyProtection#getEncryptionPaddings()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).getEncryptionPaddings()) }
|
|
170
|
+
"KeyProtection#getSignaturePaddings()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).getSignaturePaddings()) }
|
|
171
|
+
"KeyProtection#getDigests()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).getDigests()) }
|
|
172
|
+
"KeyProtection#isDigestsSpecified()Z" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).isDigestsSpecified()) }
|
|
173
|
+
"KeyProtection#getBlockModes()[Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).getBlockModes()) }
|
|
174
|
+
"KeyProtection#isRandomizedEncryptionRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).isRandomizedEncryptionRequired()) }
|
|
175
|
+
"KeyProtection#isUserAuthenticationRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).isUserAuthenticationRequired()) }
|
|
176
|
+
"KeyProtection#getUserAuthenticationValidityDurationSeconds()I" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).getUserAuthenticationValidityDurationSeconds()) }
|
|
177
|
+
"KeyProtection#isUserAuthenticationValidWhileOnBody()Z" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).isUserAuthenticationValidWhileOnBody()) }
|
|
178
|
+
"KeyProtection#isInvalidatedByBiometricEnrollment()Z" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).isInvalidatedByBiometricEnrollment()) }
|
|
179
|
+
"KeyProtection#isUserConfirmationRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).isUserConfirmationRequired()) }
|
|
180
|
+
"KeyProtection#isUserPresenceRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).isUserPresenceRequired()) }
|
|
181
|
+
"KeyProtection#isUnlockedDeviceRequired()Z" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).isUnlockedDeviceRequired()) }
|
|
182
|
+
"KeyProtection#getUserAuthenticationType()I" -> b.run { if (Build.VERSION.SDK_INT < 30) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).getUserAuthenticationType()) }
|
|
183
|
+
"KeyProtection#getMaxUsageCount()I" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).getMaxUsageCount()) }
|
|
184
|
+
"KeyProtection#getMgf1Digests()Ljava/util/Set;" -> b.run { if (Build.VERSION.SDK_INT < 35) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).getMgf1Digests()) }
|
|
185
|
+
"KeyProtection#isMgf1DigestsSpecified()Z" -> b.run { if (Build.VERSION.SDK_INT < 35) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection::class.java).isMgf1DigestsSpecified()) }
|
|
186
|
+
else -> b.unsupported(method)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private fun callKeyProtection_Builder(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
190
|
+
when (method) {
|
|
191
|
+
"KeyProtection.Builder#<init>(I)V" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(android.security.keystore.KeyProtection.Builder(b.int(b[0]))) }
|
|
192
|
+
"KeyProtection.Builder#setEncryptionPaddings([Ljava/lang/String;)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setEncryptionPaddings(*b.list(b[0]) { x1 -> b.optional(x1) { x2 -> b.string(x2) } }.toTypedArray())) }
|
|
193
|
+
"KeyProtection.Builder#setSignaturePaddings([Ljava/lang/String;)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setSignaturePaddings(*b.list(b[0]) { x1 -> b.optional(x1) { x2 -> b.string(x2) } }.toTypedArray())) }
|
|
194
|
+
"KeyProtection.Builder#setDigests([Ljava/lang/String;)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setDigests(*b.list(b[0]) { x1 -> b.optional(x1) { x2 -> b.string(x2) } }.toTypedArray())) }
|
|
195
|
+
"KeyProtection.Builder#setBlockModes([Ljava/lang/String;)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setBlockModes(*b.list(b[0]) { x1 -> b.optional(x1) { x2 -> b.string(x2) } }.toTypedArray())) }
|
|
196
|
+
"KeyProtection.Builder#setRandomizedEncryptionRequired(Z)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setRandomizedEncryptionRequired(b.boolean(b[0]))) }
|
|
197
|
+
"KeyProtection.Builder#setUserAuthenticationRequired(Z)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setUserAuthenticationRequired(b.boolean(b[0]))) }
|
|
198
|
+
"KeyProtection.Builder#setUserAuthenticationValidityDurationSeconds(I)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setUserAuthenticationValidityDurationSeconds(b.int(b[0]))) }
|
|
199
|
+
"KeyProtection.Builder#build()Landroid/security/keystore/KeyProtection;" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).build()) }
|
|
200
|
+
"KeyProtection.Builder#setUserAuthenticationValidWhileOnBody(Z)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setUserAuthenticationValidWhileOnBody(b.boolean(b[0]))) }
|
|
201
|
+
"KeyProtection.Builder#setInvalidatedByBiometricEnrollment(Z)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 24) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setInvalidatedByBiometricEnrollment(b.boolean(b[0]))) }
|
|
202
|
+
"KeyProtection.Builder#setUserConfirmationRequired(Z)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setUserConfirmationRequired(b.boolean(b[0]))) }
|
|
203
|
+
"KeyProtection.Builder#setUserPresenceRequired(Z)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setUserPresenceRequired(b.boolean(b[0]))) }
|
|
204
|
+
"KeyProtection.Builder#setUnlockedDeviceRequired(Z)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setUnlockedDeviceRequired(b.boolean(b[0]))) }
|
|
205
|
+
"KeyProtection.Builder#setUserAuthenticationParameters(II)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 30) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setUserAuthenticationParameters(b.int(b[0]), b.int(b[1]))) }
|
|
206
|
+
"KeyProtection.Builder#setIsStrongBoxBacked(Z)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setIsStrongBoxBacked(b.boolean(b[0]))) }
|
|
207
|
+
"KeyProtection.Builder#setMaxUsageCount(I)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 31) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setMaxUsageCount(b.int(b[0]))) }
|
|
208
|
+
"KeyProtection.Builder#setMgf1Digests([Ljava/lang/String;)Landroid/security/keystore/KeyProtection\$Builder;" -> b.run { if (Build.VERSION.SDK_INT < 35) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.KeyProtection.Builder::class.java).setMgf1Digests(*b.list(b[0]) { x1 -> b.optional(x1) { x2 -> b.string(x2) } }.toTypedArray())) }
|
|
209
|
+
else -> b.unsupported(method)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private fun callSecureKeyImportUnavailableException(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
213
|
+
when (method) {
|
|
214
|
+
"SecureKeyImportUnavailableException#<init>()V" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(android.security.keystore.SecureKeyImportUnavailableException()) }
|
|
215
|
+
"SecureKeyImportUnavailableException#<init>(Ljava/lang/String;)V" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(android.security.keystore.SecureKeyImportUnavailableException(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
216
|
+
else -> b.unsupported(method)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private fun callStrongBoxUnavailableException(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
220
|
+
when (method) {
|
|
221
|
+
"StrongBoxUnavailableException#<init>()V" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(android.security.keystore.StrongBoxUnavailableException()) }
|
|
222
|
+
"StrongBoxUnavailableException#<init>(Ljava/lang/String;)V" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(android.security.keystore.StrongBoxUnavailableException(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
223
|
+
else -> b.unsupported(method)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private fun callUserNotAuthenticatedException(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
227
|
+
when (method) {
|
|
228
|
+
"UserNotAuthenticatedException#<init>()V" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(android.security.keystore.UserNotAuthenticatedException()) }
|
|
229
|
+
"UserNotAuthenticatedException#<init>(Ljava/lang/String;)V" -> b.run { if (Build.VERSION.SDK_INT < 23) throw TokamakBinding.unavailable; b.encode(android.security.keystore.UserNotAuthenticatedException(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
230
|
+
else -> b.unsupported(method)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private fun callUserPresenceUnavailableException(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
234
|
+
when (method) {
|
|
235
|
+
"UserPresenceUnavailableException#<init>()V" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(android.security.keystore.UserPresenceUnavailableException()) }
|
|
236
|
+
"UserPresenceUnavailableException#<init>(Ljava/lang/String;)V" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(android.security.keystore.UserPresenceUnavailableException(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
237
|
+
else -> b.unsupported(method)
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
private fun callWrappedKeyEntry(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
241
|
+
when (method) {
|
|
242
|
+
"WrappedKeyEntry#getWrappedKeyBytes()[B" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.WrappedKeyEntry::class.java).getWrappedKeyBytes()) }
|
|
243
|
+
"WrappedKeyEntry#getWrappingKeyAlias()Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.WrappedKeyEntry::class.java).getWrappingKeyAlias()) }
|
|
244
|
+
"WrappedKeyEntry#getTransformation()Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 28) throw TokamakBinding.unavailable; b.encode(b.target(android.security.keystore.WrappedKeyEntry::class.java).getTransformation()) }
|
|
245
|
+
else -> b.unsupported(method)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private fun callKeyStore(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
249
|
+
when (method) {
|
|
250
|
+
"KeyStore#getInstance(Ljava/lang/String;)Ljava/security/KeyStore;" -> b.run { b.encode(java.security.KeyStore.getInstance(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
251
|
+
"KeyStore#getInstance(Ljava/lang/String;Ljava/lang/String;)Ljava/security/KeyStore;" -> b.run { b.encode(java.security.KeyStore.getInstance(b.optional(b[0]) { x1 -> b.string(x1) }, b.optional(b[1]) { x1 -> b.string(x1) })) }
|
|
252
|
+
"KeyStore#getDefaultType()Ljava/lang/String;" -> b.run { b.encode(java.security.KeyStore.getDefaultType()) }
|
|
253
|
+
"KeyStore#getType()Ljava/lang/String;" -> b.run { b.encode(b.target(java.security.KeyStore::class.java).getType()) }
|
|
254
|
+
"KeyStore#deleteEntry(Ljava/lang/String;)V" -> b.run { b.target(java.security.KeyStore::class.java).deleteEntry(b.optional(b[0]) { x1 -> b.string(x1) }); null }
|
|
255
|
+
"KeyStore#containsAlias(Ljava/lang/String;)Z" -> b.run { b.encode(b.target(java.security.KeyStore::class.java).containsAlias(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
256
|
+
"KeyStore#size()I" -> b.run { b.encode(b.target(java.security.KeyStore::class.java).size()) }
|
|
257
|
+
"KeyStore#isKeyEntry(Ljava/lang/String;)Z" -> b.run { b.encode(b.target(java.security.KeyStore::class.java).isKeyEntry(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
258
|
+
"KeyStore#isCertificateEntry(Ljava/lang/String;)Z" -> b.run { b.encode(b.target(java.security.KeyStore::class.java).isCertificateEntry(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
259
|
+
"KeyStore#store(Ljava/security/KeyStore\$LoadStoreParameter;)V" -> b.run { b.target(java.security.KeyStore::class.java).store(b.optional(b[0]) { x1 -> b.obj(x1, java.security.KeyStore.LoadStoreParameter::class.java) }); null }
|
|
260
|
+
"KeyStore#load(Ljava/security/KeyStore\$LoadStoreParameter;)V" -> b.run { b.target(java.security.KeyStore::class.java).load(b.optional(b[0]) { x1 -> b.obj(x1, java.security.KeyStore.LoadStoreParameter::class.java) }); null }
|
|
261
|
+
"KeyStore#getEntry(Ljava/lang/String;Ljava/security/KeyStore\$ProtectionParameter;)Ljava/security/KeyStore\$Entry;" -> b.run { b.encode(b.target(java.security.KeyStore::class.java).getEntry(b.optional(b[0]) { x1 -> b.string(x1) }, b.optional(b[1]) { x1 -> b.obj(x1, java.security.KeyStore.ProtectionParameter::class.java) })) }
|
|
262
|
+
"KeyStore#setEntry(Ljava/lang/String;Ljava/security/KeyStore\$Entry;Ljava/security/KeyStore\$ProtectionParameter;)V" -> b.run { b.target(java.security.KeyStore::class.java).setEntry(b.optional(b[0]) { x1 -> b.string(x1) }, b.optional(b[1]) { x1 -> b.obj(x1, java.security.KeyStore.Entry::class.java) }, b.optional(b[2]) { x1 -> b.obj(x1, java.security.KeyStore.ProtectionParameter::class.java) }); null }
|
|
263
|
+
else -> b.unsupported(method)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private fun callKeyStore_Builder(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
267
|
+
when (method) {
|
|
268
|
+
"KeyStore.Builder#getKeyStore()Ljava/security/KeyStore;" -> b.run { b.encode(b.target(java.security.KeyStore.Builder::class.java).getKeyStore()) }
|
|
269
|
+
"KeyStore.Builder#getProtectionParameter(Ljava/lang/String;)Ljava/security/KeyStore\$ProtectionParameter;" -> b.run { b.encode(b.target(java.security.KeyStore.Builder::class.java).getProtectionParameter(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
270
|
+
"KeyStore.Builder#newInstance(Ljava/security/KeyStore;Ljava/security/KeyStore\$ProtectionParameter;)Ljava/security/KeyStore\$Builder;" -> b.run { b.encode(java.security.KeyStore.Builder.newInstance(b.optional(b[0]) { x1 -> b.obj(x1, java.security.KeyStore::class.java) }, b.optional(b[1]) { x1 -> b.obj(x1, java.security.KeyStore.ProtectionParameter::class.java) })) }
|
|
271
|
+
else -> b.unsupported(method)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private fun callKeyStore_Entry(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
275
|
+
when (method) {
|
|
276
|
+
"KeyStore.Entry#getAttributes()Ljava/util/Set;" -> b.run { if (Build.VERSION.SDK_INT < 26) throw TokamakBinding.unavailable; b.encode(b.target(java.security.KeyStore.Entry::class.java).getAttributes()) }
|
|
277
|
+
else -> b.unsupported(method)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private fun callKeyStore_Entry_Attribute(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
281
|
+
when (method) {
|
|
282
|
+
"KeyStore.Entry.Attribute#getName()Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 26) throw TokamakBinding.unavailable; b.encode(b.target(java.security.KeyStore.Entry.Attribute::class.java).getName()) }
|
|
283
|
+
"KeyStore.Entry.Attribute#getValue()Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 26) throw TokamakBinding.unavailable; b.encode(b.target(java.security.KeyStore.Entry.Attribute::class.java).getValue()) }
|
|
284
|
+
else -> b.unsupported(method)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private fun callKeyStore_LoadStoreParameter(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
288
|
+
when (method) {
|
|
289
|
+
"KeyStore.LoadStoreParameter#getProtectionParameter()Ljava/security/KeyStore\$ProtectionParameter;" -> b.run { b.encode(b.target(java.security.KeyStore.LoadStoreParameter::class.java).getProtectionParameter()) }
|
|
290
|
+
else -> b.unsupported(method)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private fun callKeyStore_PasswordProtection(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
294
|
+
when (method) {
|
|
295
|
+
"KeyStore.PasswordProtection#<init>([C)V" -> b.run { b.encode(java.security.KeyStore.PasswordProtection(b.optional(b[0]) { x1 -> b.list(x1) { x2 -> b.char(x2) }.toCharArray() })) }
|
|
296
|
+
"KeyStore.PasswordProtection#getPassword()[C" -> b.run { b.encode(b.target(java.security.KeyStore.PasswordProtection::class.java).getPassword()) }
|
|
297
|
+
"KeyStore.PasswordProtection#destroy()V" -> b.run { b.target(java.security.KeyStore.PasswordProtection::class.java).destroy(); null }
|
|
298
|
+
"KeyStore.PasswordProtection#isDestroyed()Z" -> b.run { b.encode(b.target(java.security.KeyStore.PasswordProtection::class.java).isDestroyed()) }
|
|
299
|
+
"KeyStore.PasswordProtection#getProtectionAlgorithm()Ljava/lang/String;" -> b.run { if (Build.VERSION.SDK_INT < 26) throw TokamakBinding.unavailable; b.encode(b.target(java.security.KeyStore.PasswordProtection::class.java).getProtectionAlgorithm()) }
|
|
300
|
+
else -> b.unsupported(method)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
private fun callKeyStore_PrivateKeyEntry(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
304
|
+
when (method) {
|
|
305
|
+
"KeyStore.PrivateKeyEntry#getAttributes()Ljava/util/Set;" -> b.run { b.encode(b.target(java.security.KeyStore.PrivateKeyEntry::class.java).getAttributes()) }
|
|
306
|
+
"KeyStore.PrivateKeyEntry#toString()Ljava/lang/String;" -> b.run { b.encode(b.target(java.security.KeyStore.PrivateKeyEntry::class.java).toString()) }
|
|
307
|
+
else -> b.unsupported(method)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
private fun callKeyStore_SecretKeyEntry(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
311
|
+
when (method) {
|
|
312
|
+
"KeyStore.SecretKeyEntry#getAttributes()Ljava/util/Set;" -> b.run { b.encode(b.target(java.security.KeyStore.SecretKeyEntry::class.java).getAttributes()) }
|
|
313
|
+
"KeyStore.SecretKeyEntry#toString()Ljava/lang/String;" -> b.run { b.encode(b.target(java.security.KeyStore.SecretKeyEntry::class.java).toString()) }
|
|
314
|
+
else -> b.unsupported(method)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
private fun callKeyStore_TrustedCertificateEntry(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
318
|
+
when (method) {
|
|
319
|
+
"KeyStore.TrustedCertificateEntry#getAttributes()Ljava/util/Set;" -> b.run { b.encode(b.target(java.security.KeyStore.TrustedCertificateEntry::class.java).getAttributes()) }
|
|
320
|
+
"KeyStore.TrustedCertificateEntry#toString()Ljava/lang/String;" -> b.run { b.encode(b.target(java.security.KeyStore.TrustedCertificateEntry::class.java).toString()) }
|
|
321
|
+
else -> b.unsupported(method)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
private fun callCipher(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
325
|
+
when (method) {
|
|
326
|
+
"Cipher#getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;" -> b.run { b.encode(javax.crypto.Cipher.getInstance(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
327
|
+
"Cipher#getInstance(Ljava/lang/String;Ljava/lang/String;)Ljavax/crypto/Cipher;" -> b.run { b.encode(javax.crypto.Cipher.getInstance(b.optional(b[0]) { x1 -> b.string(x1) }, b.optional(b[1]) { x1 -> b.string(x1) })) }
|
|
328
|
+
"Cipher#getAlgorithm()Ljava/lang/String;" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).getAlgorithm()) }
|
|
329
|
+
"Cipher#getBlockSize()I" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).getBlockSize()) }
|
|
330
|
+
"Cipher#getOutputSize(I)I" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).getOutputSize(b.int(b[0]))) }
|
|
331
|
+
"Cipher#getIV()[B" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).getIV()) }
|
|
332
|
+
"Cipher#update([B)[B" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).update(b.optional(b[0]) { x1 -> b.bytes(x1) })) }
|
|
333
|
+
"Cipher#update([BII)[B" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).update(b.optional(b[0]) { x1 -> b.bytes(x1) }, b.int(b[1]), b.int(b[2]))) }
|
|
334
|
+
"Cipher#update([BII[B)I" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).update(b.optional(b[0]) { x1 -> b.bytes(x1) }, b.int(b[1]), b.int(b[2]), b.optional(b[3]) { x1 -> b.bytes(x1) })) }
|
|
335
|
+
"Cipher#update([BII[BI)I" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).update(b.optional(b[0]) { x1 -> b.bytes(x1) }, b.int(b[1]), b.int(b[2]), b.optional(b[3]) { x1 -> b.bytes(x1) }, b.int(b[4]))) }
|
|
336
|
+
"Cipher#doFinal()[B" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).doFinal()) }
|
|
337
|
+
"Cipher#doFinal([BI)I" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).doFinal(b.optional(b[0]) { x1 -> b.bytes(x1) }, b.int(b[1]))) }
|
|
338
|
+
"Cipher#doFinal([B)[B" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).doFinal(b.optional(b[0]) { x1 -> b.bytes(x1) })) }
|
|
339
|
+
"Cipher#doFinal([BII)[B" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).doFinal(b.optional(b[0]) { x1 -> b.bytes(x1) }, b.int(b[1]), b.int(b[2]))) }
|
|
340
|
+
"Cipher#doFinal([BII[B)I" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).doFinal(b.optional(b[0]) { x1 -> b.bytes(x1) }, b.int(b[1]), b.int(b[2]), b.optional(b[3]) { x1 -> b.bytes(x1) })) }
|
|
341
|
+
"Cipher#doFinal([BII[BI)I" -> b.run { b.encode(b.target(javax.crypto.Cipher::class.java).doFinal(b.optional(b[0]) { x1 -> b.bytes(x1) }, b.int(b[1]), b.int(b[2]), b.optional(b[3]) { x1 -> b.bytes(x1) }, b.int(b[4]))) }
|
|
342
|
+
"Cipher#getMaxAllowedKeyLength(Ljava/lang/String;)I" -> b.run { b.encode(javax.crypto.Cipher.getMaxAllowedKeyLength(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
343
|
+
"Cipher#updateAAD([B)V" -> b.run { if (Build.VERSION.SDK_INT < 19) throw TokamakBinding.unavailable; b.target(javax.crypto.Cipher::class.java).updateAAD(b.optional(b[0]) { x1 -> b.bytes(x1) }); null }
|
|
344
|
+
"Cipher#updateAAD([BII)V" -> b.run { if (Build.VERSION.SDK_INT < 19) throw TokamakBinding.unavailable; b.target(javax.crypto.Cipher::class.java).updateAAD(b.optional(b[0]) { x1 -> b.bytes(x1) }, b.int(b[1]), b.int(b[2])); null }
|
|
345
|
+
else -> b.unsupported(method)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
private fun callKeyGenerator(method: String, b: TokamakBinding): (() -> Unit)? =
|
|
349
|
+
when (method) {
|
|
350
|
+
"KeyGenerator#getAlgorithm()Ljava/lang/String;" -> b.run { b.encode(b.target(javax.crypto.KeyGenerator::class.java).getAlgorithm()) }
|
|
351
|
+
"KeyGenerator#getInstance(Ljava/lang/String;)Ljavax/crypto/KeyGenerator;" -> b.run { b.encode(javax.crypto.KeyGenerator.getInstance(b.optional(b[0]) { x1 -> b.string(x1) })) }
|
|
352
|
+
"KeyGenerator#getInstance(Ljava/lang/String;Ljava/lang/String;)Ljavax/crypto/KeyGenerator;" -> b.run { b.encode(javax.crypto.KeyGenerator.getInstance(b.optional(b[0]) { x1 -> b.string(x1) }, b.optional(b[1]) { x1 -> b.string(x1) })) }
|
|
353
|
+
"KeyGenerator#init(I)V" -> b.run { b.target(javax.crypto.KeyGenerator::class.java).init(b.int(b[0])); null }
|
|
354
|
+
else -> b.unsupported(method)
|
|
355
|
+
}
|
|
356
|
+
}
|
|
@@ -2,6 +2,7 @@ package com.tokamak.plugins.securestorage
|
|
|
2
2
|
|
|
3
3
|
import android.hardware.biometrics.BiometricManager.Authenticators
|
|
4
4
|
import android.hardware.biometrics.BiometricPrompt
|
|
5
|
+
import android.os.CancellationSignal
|
|
5
6
|
import android.security.keystore.KeyGenParameterSpec
|
|
6
7
|
import android.security.keystore.KeyInfo
|
|
7
8
|
import android.security.keystore.KeyPermanentlyInvalidatedException
|
|
@@ -33,6 +34,7 @@ import java.security.PublicKey
|
|
|
33
34
|
import java.security.SecureRandom
|
|
34
35
|
import java.security.spec.MGF1ParameterSpec
|
|
35
36
|
import java.security.spec.X509EncodedKeySpec
|
|
37
|
+
import java.util.concurrent.Executor
|
|
36
38
|
import java.util.concurrent.Executors
|
|
37
39
|
import javax.crypto.BadPaddingException
|
|
38
40
|
import javax.crypto.Cipher
|
|
@@ -61,32 +63,36 @@ class TokamakSecureStoragePlugin(
|
|
|
61
63
|
private val keyStore = KeyStore.getInstance(KEYSTORE).apply { load(null) }
|
|
62
64
|
private val random = SecureRandom()
|
|
63
65
|
|
|
64
|
-
override fun
|
|
66
|
+
override fun executor(method: String) = worker
|
|
67
|
+
|
|
68
|
+
override fun call(method: String, arguments: Any?, reply: TokamakPluginReply): (() -> Unit)? {
|
|
69
|
+
val cancellation = CancellationSignal()
|
|
65
70
|
when (method) {
|
|
66
|
-
"create" ->
|
|
71
|
+
"create" -> attempt(reply) {
|
|
67
72
|
store(request(arguments), Write.CREATE)
|
|
68
73
|
reply(Result.success(null))
|
|
69
74
|
}
|
|
70
|
-
"replace" ->
|
|
75
|
+
"replace" -> attempt(reply) {
|
|
71
76
|
store(request(arguments), Write.REPLACE)
|
|
72
77
|
reply(Result.success(null))
|
|
73
78
|
}
|
|
74
|
-
"set" ->
|
|
79
|
+
"set" -> attempt(reply) {
|
|
75
80
|
store(request(arguments), Write.SET)
|
|
76
81
|
reply(Result.success(null))
|
|
77
82
|
}
|
|
78
|
-
"get" ->
|
|
79
|
-
"delete" ->
|
|
83
|
+
"get" -> attempt(reply) { get(request(arguments), reply, cancellation) }
|
|
84
|
+
"delete" -> attempt(reply) {
|
|
80
85
|
delete(request(arguments).requireString("name"))
|
|
81
86
|
reply(Result.success(null))
|
|
82
87
|
}
|
|
83
|
-
"clear" ->
|
|
88
|
+
"clear" -> attempt(reply) {
|
|
84
89
|
request(arguments) // Rejects keychainGroup.
|
|
85
90
|
clear()
|
|
86
91
|
reply(Result.success(null))
|
|
87
92
|
}
|
|
88
|
-
else -> super.call(method, arguments, reply)
|
|
93
|
+
else -> return super.call(method, arguments, reply)
|
|
89
94
|
}
|
|
95
|
+
return { cancellation.cancel() }
|
|
90
96
|
}
|
|
91
97
|
|
|
92
98
|
/** The call's arguments, rejecting the Apple-only `keychainGroup`. */
|
|
@@ -98,15 +104,14 @@ class TokamakSecureStoragePlugin(
|
|
|
98
104
|
return request
|
|
99
105
|
}
|
|
100
106
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
/** Runs [operation], replying with what it throws. */
|
|
108
|
+
private fun attempt(reply: TokamakPluginReply, operation: () -> Unit) {
|
|
109
|
+
runCatching(operation).onFailure { reply(Result.failure(pluginError(it))) }
|
|
110
|
+
}
|
|
105
111
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
112
|
+
/** Runs [operation] on [executor] unless the call was cancelled first. */
|
|
113
|
+
private fun resume(executor: Executor, reply: TokamakPluginReply, cancellation: CancellationSignal, operation: () -> Unit) =
|
|
114
|
+
executor.execute { if (!cancellation.isCanceled) attempt(reply, operation) }
|
|
110
115
|
|
|
111
116
|
private fun store(request: JSONObject, mode: Write) {
|
|
112
117
|
val name = request.requireString("name")
|
|
@@ -185,7 +190,7 @@ class TokamakSecureStoragePlugin(
|
|
|
185
190
|
return StoredValue(keyId, wrapped, iv, sealed)
|
|
186
191
|
}
|
|
187
192
|
|
|
188
|
-
private fun get(request: JSONObject, reply: TokamakPluginReply) {
|
|
193
|
+
private fun get(request: JSONObject, reply: TokamakPluginReply, cancellation: CancellationSignal) {
|
|
189
194
|
val name = request.requireString("name")
|
|
190
195
|
val prompt = request.optionalString("prompt")
|
|
191
196
|
val stored = read(file(name)) ?: throw itemNotFound()
|
|
@@ -204,7 +209,7 @@ class TokamakSecureStoragePlugin(
|
|
|
204
209
|
val authenticators =
|
|
205
210
|
if (credential) Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL
|
|
206
211
|
else Authenticators.BIOMETRIC_STRONG
|
|
207
|
-
authenticate(authenticators, prompt, unwrap, stored, reply)
|
|
212
|
+
authenticate(authenticators, prompt, unwrap, stored, reply, cancellation)
|
|
208
213
|
}
|
|
209
214
|
|
|
210
215
|
/** Authorises [unwrap] with the device owner's authentication, then replies with the opened value. */
|
|
@@ -214,11 +219,12 @@ class TokamakSecureStoragePlugin(
|
|
|
214
219
|
unwrap: Cipher,
|
|
215
220
|
stored: StoredValue,
|
|
216
221
|
reply: TokamakPluginReply,
|
|
222
|
+
cancellation: CancellationSignal,
|
|
217
223
|
) {
|
|
218
224
|
val title = prompt?.takeIf { it.isNotEmpty() } ?: context.applicationInfo.loadLabel(context.packageManager)
|
|
219
|
-
|
|
220
|
-
host.authenticateOwner(title, authenticators, BiometricPrompt.CryptoObject(unwrap), reply) {
|
|
221
|
-
|
|
225
|
+
resume(context.mainExecutor, reply, cancellation) {
|
|
226
|
+
host.authenticateOwner(title, authenticators, BiometricPrompt.CryptoObject(unwrap), reply, cancellation) {
|
|
227
|
+
resume(worker, reply, cancellation) { reply(Result.success(open(stored, unwrap))) }
|
|
222
228
|
}
|
|
223
229
|
}
|
|
224
230
|
}
|