@tokamakdev/plugin-secure-storage 0.1.0-beta.107 → 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 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 { secureStorage } from "@tokamakdev/plugin-secure-storage";
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 call(method: String, arguments: Any?, reply: TokamakPluginReply) {
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" -> execute(reply) {
71
+ "create" -> attempt(reply) {
67
72
  store(request(arguments), Write.CREATE)
68
73
  reply(Result.success(null))
69
74
  }
70
- "replace" -> execute(reply) {
75
+ "replace" -> attempt(reply) {
71
76
  store(request(arguments), Write.REPLACE)
72
77
  reply(Result.success(null))
73
78
  }
74
- "set" -> execute(reply) {
79
+ "set" -> attempt(reply) {
75
80
  store(request(arguments), Write.SET)
76
81
  reply(Result.success(null))
77
82
  }
78
- "get" -> execute(reply) { get(request(arguments), reply) }
79
- "delete" -> execute(reply) {
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" -> execute(reply) {
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
- private fun execute(reply: TokamakPluginReply, operation: () -> Unit) =
102
- worker.execute {
103
- runCatching(operation).onFailure { reply(Result.failure(pluginError(it))) }
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
- private fun onUiThread(reply: TokamakPluginReply, operation: () -> Unit) =
107
- context.mainExecutor.execute {
108
- runCatching(operation).onFailure { reply(Result.failure(pluginError(it))) }
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
- onUiThread(reply) {
220
- host.authenticateOwner(title, authenticators, BiometricPrompt.CryptoObject(unwrap), reply) {
221
- execute(reply) { reply(Result.success(open(stored, unwrap))) }
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
  }