tauri-plugin-secure-element-api 0.1.0-alpha.1

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 ADDED
@@ -0,0 +1,154 @@
1
+ # Tauri Plugin Secure Element
2
+
3
+ A Tauri plugin for secure element functionality on iOS (Secure Enclave) and Android (Strongbox and TEE).
4
+
5
+ ## Features
6
+
7
+ - Generate secure keys using hardware-backed secure storage
8
+ - Sign data with keys stored in secure elements
9
+ - List and manage secure keys
10
+ - Check secure element support on the device
11
+ - Support for biometric and PIN authentication modes
12
+ - Cross-platform support for iOS and Android
13
+
14
+ ## Installation
15
+
16
+ ### npm
17
+
18
+ ```bash
19
+ npm install tauri-plugin-secure-element-api
20
+ # or
21
+ pnpm add tauri-plugin-secure-element-api
22
+ # or
23
+ yarn add tauri-plugin-secure-element-api
24
+ ```
25
+
26
+ ### Cargo
27
+
28
+ ```toml
29
+ [dependencies]
30
+ tauri-plugin-secure-element = "0.1.0"
31
+ ```
32
+
33
+ ## Setup
34
+
35
+ Add the plugin to your `tauri.conf.json`:
36
+
37
+ ```json
38
+ {
39
+ "plugins": {
40
+ "secure-element": {
41
+ "all": true
42
+ }
43
+ }
44
+ }
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ ```typescript
50
+ import {
51
+ checkSecureElementSupport,
52
+ generateSecureKey,
53
+ listKeys,
54
+ signWithKey,
55
+ deleteKey,
56
+ type AuthenticationMode,
57
+ } from "tauri-plugin-secure-element-api";
58
+
59
+ // Check if secure element is supported
60
+ const support = await checkSecureElementSupport();
61
+ console.log("Secure element supported:", support.secureElementSupported);
62
+
63
+ // Generate a new secure key
64
+ const { publicKey, keyName } = await generateSecureKey(
65
+ "my-key-name",
66
+ "pinOrBiometric" // or 'none' or 'biometricOnly'
67
+ );
68
+
69
+ // List all keys
70
+ const keys = await listKeys();
71
+
72
+ // Sign data with a key
73
+ const data = new Uint8Array([1, 2, 3, 4]);
74
+ const signature = await signWithKey("my-key-name", data);
75
+
76
+ // Delete a key
77
+ await deleteKey("my-key-name");
78
+ ```
79
+
80
+ ## API Reference
81
+
82
+ ### `checkSecureElementSupport()`
83
+
84
+ Returns information about secure element support on the device.
85
+
86
+ **Returns:** `Promise<SecureElementSupport>`
87
+
88
+ ```typescript
89
+ interface SecureElementSupport {
90
+ secureElementSupported: boolean;
91
+ teeSupported: boolean;
92
+ canEnforceBiometricOnly: boolean;
93
+ }
94
+ ```
95
+
96
+ ### `generateSecureKey(keyName: string, authMode?: AuthenticationMode)`
97
+
98
+ Generates a new secure key in the device's secure element.
99
+
100
+ **Parameters:**
101
+
102
+ - `keyName`: Unique name for the key
103
+ - `authMode`: Authentication mode (`'none'`, `'pinOrBiometric'`, or `'biometricOnly'`)
104
+
105
+ **Returns:** `Promise<{ publicKey: string; keyName: string }>`
106
+
107
+ ### `listKeys(keyName?: string, publicKey?: string)`
108
+
109
+ Lists keys stored in the secure element. Can filter by key name or public key.
110
+
111
+ **Returns:** `Promise<KeyInfo[]>`
112
+
113
+ ```typescript
114
+ interface KeyInfo {
115
+ keyName: string;
116
+ publicKey: string;
117
+ requiresAuthentication?: boolean;
118
+ }
119
+ ```
120
+
121
+ ### `signWithKey(keyName: string, data: Uint8Array)`
122
+
123
+ Signs data using a key stored in the secure element.
124
+
125
+ **Parameters:**
126
+
127
+ - `keyName`: Name of the key to use
128
+ - `data`: Data to sign as `Uint8Array`
129
+
130
+ **Returns:** `Promise<Uint8Array>` - The signature
131
+
132
+ ### `deleteKey(keyName?: string, publicKey?: string)`
133
+
134
+ Deletes a key from the secure element. At least one parameter must be provided.
135
+
136
+ **Returns:** `Promise<boolean>` - Success status
137
+
138
+ ## Platform Support
139
+
140
+ - **iOS**: Uses Secure Enclave for key generation and signing
141
+ - **Android**: Uses Strongbox and TEE (Trusted Execution Environment) when available
142
+
143
+ ## License
144
+
145
+ Apache-2.0
146
+
147
+ ## Contributing
148
+
149
+ Contributions are welcome! Please feel free to submit a Pull Request.
150
+
151
+ ## Links
152
+
153
+ - [Repository](https://github.com/dkackman/tauri-plugin-secure-element)
154
+ - [Issues](https://github.com/dkackman/tauri-plugin-secure-element/issues)
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+
3
+ var core = require('@tauri-apps/api/core');
4
+
5
+ async function ping(value) {
6
+ return await core.invoke("plugin:secure-element|ping", {
7
+ payload: {
8
+ value,
9
+ },
10
+ }).then((r) => (r.value ? r.value : null));
11
+ }
12
+ async function generateSecureKey(keyName, authMode = "pinOrBiometric") {
13
+ return await core.invoke("plugin:secure-element|generate_secure_key", {
14
+ payload: {
15
+ keyName,
16
+ authMode,
17
+ },
18
+ });
19
+ }
20
+ async function listKeys(keyName, publicKey) {
21
+ return await core.invoke("plugin:secure-element|list_keys", {
22
+ payload: {
23
+ keyName: keyName || null,
24
+ publicKey: publicKey || null,
25
+ },
26
+ }).then((r) => r.keys);
27
+ }
28
+ async function signWithKey(keyName, data) {
29
+ return await core.invoke("plugin:secure-element|sign_with_key", {
30
+ payload: {
31
+ keyName,
32
+ data: Array.from(data),
33
+ },
34
+ }).then((r) => new Uint8Array(r.signature));
35
+ }
36
+ /**
37
+ * Delete a key by name or by public key.
38
+ * At least one of keyName or publicKey must be provided.
39
+ */
40
+ async function deleteKey(keyName, publicKey) {
41
+ return await core.invoke("plugin:secure-element|delete_key", {
42
+ payload: {
43
+ keyName: keyName || null,
44
+ publicKey: publicKey || null,
45
+ },
46
+ }).then((r) => r.success);
47
+ }
48
+ async function checkSecureElementSupport() {
49
+ const result = await core.invoke("plugin:secure-element|check_secure_element_support");
50
+ return result;
51
+ }
52
+
53
+ exports.checkSecureElementSupport = checkSecureElementSupport;
54
+ exports.deleteKey = deleteKey;
55
+ exports.generateSecureKey = generateSecureKey;
56
+ exports.listKeys = listKeys;
57
+ exports.ping = ping;
58
+ exports.signWithKey = signWithKey;
@@ -0,0 +1,24 @@
1
+ export interface KeyInfo {
2
+ keyName: string;
3
+ publicKey: string;
4
+ requiresAuthentication?: boolean;
5
+ }
6
+ export declare function ping(value: string): Promise<string | null>;
7
+ export type AuthenticationMode = "none" | "pinOrBiometric" | "biometricOnly";
8
+ export declare function generateSecureKey(keyName: string, authMode?: AuthenticationMode): Promise<{
9
+ publicKey: string;
10
+ keyName: string;
11
+ }>;
12
+ export declare function listKeys(keyName?: string, publicKey?: string): Promise<KeyInfo[]>;
13
+ export declare function signWithKey(keyName: string, data: Uint8Array): Promise<Uint8Array>;
14
+ /**
15
+ * Delete a key by name or by public key.
16
+ * At least one of keyName or publicKey must be provided.
17
+ */
18
+ export declare function deleteKey(keyName?: string, publicKey?: string): Promise<boolean>;
19
+ export interface SecureElementSupport {
20
+ secureElementSupported: boolean;
21
+ teeSupported: boolean;
22
+ canEnforceBiometricOnly: boolean;
23
+ }
24
+ export declare function checkSecureElementSupport(): Promise<SecureElementSupport>;
@@ -0,0 +1,51 @@
1
+ import { invoke } from '@tauri-apps/api/core';
2
+
3
+ async function ping(value) {
4
+ return await invoke("plugin:secure-element|ping", {
5
+ payload: {
6
+ value,
7
+ },
8
+ }).then((r) => (r.value ? r.value : null));
9
+ }
10
+ async function generateSecureKey(keyName, authMode = "pinOrBiometric") {
11
+ return await invoke("plugin:secure-element|generate_secure_key", {
12
+ payload: {
13
+ keyName,
14
+ authMode,
15
+ },
16
+ });
17
+ }
18
+ async function listKeys(keyName, publicKey) {
19
+ return await invoke("plugin:secure-element|list_keys", {
20
+ payload: {
21
+ keyName: keyName || null,
22
+ publicKey: publicKey || null,
23
+ },
24
+ }).then((r) => r.keys);
25
+ }
26
+ async function signWithKey(keyName, data) {
27
+ return await invoke("plugin:secure-element|sign_with_key", {
28
+ payload: {
29
+ keyName,
30
+ data: Array.from(data),
31
+ },
32
+ }).then((r) => new Uint8Array(r.signature));
33
+ }
34
+ /**
35
+ * Delete a key by name or by public key.
36
+ * At least one of keyName or publicKey must be provided.
37
+ */
38
+ async function deleteKey(keyName, publicKey) {
39
+ return await invoke("plugin:secure-element|delete_key", {
40
+ payload: {
41
+ keyName: keyName || null,
42
+ publicKey: publicKey || null,
43
+ },
44
+ }).then((r) => r.success);
45
+ }
46
+ async function checkSecureElementSupport() {
47
+ const result = await invoke("plugin:secure-element|check_secure_element_support");
48
+ return result;
49
+ }
50
+
51
+ export { checkSecureElementSupport, deleteKey, generateSecureKey, listKeys, ping, signWithKey };
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "tauri-plugin-secure-element-api",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "Tauri plugin for secure element use on iOS (Secure Enclave) and Android (Strongbox and TEE).",
5
+ "repository": "https://github.com/dkackman/tauri-plugin-secure-element",
6
+ "license": "Apache-2.0",
7
+ "author": "Don Kackman<dkackman@gmail.com>",
8
+ "homepage": "https://github.com/dkackman/tauri-plugin-secure-element",
9
+ "bugs": "https://github.com/dkackman/tauri-plugin-secure-element/issues",
10
+ "keywords": [
11
+ "tauri",
12
+ "tauri-plugin",
13
+ "secure-element",
14
+ "secure-enclave",
15
+ "strongbox",
16
+ "tee",
17
+ "cryptography",
18
+ "keychain",
19
+ "keystore",
20
+ "mobile",
21
+ "ios",
22
+ "android"
23
+ ],
24
+ "type": "module",
25
+ "types": "./dist-js/index.d.ts",
26
+ "main": "./dist-js/index.cjs",
27
+ "module": "./dist-js/index.js",
28
+ "exports": {
29
+ "types": "./dist-js/index.d.ts",
30
+ "import": "./dist-js/index.js",
31
+ "require": "./dist-js/index.cjs"
32
+ },
33
+ "files": [
34
+ "dist-js",
35
+ "README.md"
36
+ ],
37
+ "dependencies": {
38
+ "@tauri-apps/api": "^2.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@rollup/plugin-typescript": "^12.0.0",
42
+ "@naturalcycles/ktlint": "^1.16.0",
43
+ "prettier": "^3.7.4",
44
+ "rollup": "^4.9.6",
45
+ "typescript": "^5.3.3",
46
+ "tslib": "^2.6.2"
47
+ },
48
+ "scripts": {
49
+ "build": "rollup -c",
50
+ "pretest": "pnpm build",
51
+ "format": "prettier --write . && cargo fmt && swiftformat ios/ 2>/dev/null || echo 'Note: swiftformat not installed. Install with: brew install swiftformat' && pnpm format:kotlin",
52
+ "format:check": "prettier --check . && cargo fmt --check && (swiftformat --lint ios/ 2>/dev/null || echo 'Note: swiftformat not installed') && pnpm format:check:kotlin",
53
+ "format:js": "prettier --write .",
54
+ "format:rust": "cargo fmt",
55
+ "format:swift": "swiftformat ios/ || echo 'Note: swiftformat not installed. Install with: brew install swiftformat'",
56
+ "format:kotlin": "ktlint -F 'android/src/**/*.kt'",
57
+ "format:check:kotlin": "ktlint 'android/src/**/*.kt'",
58
+ "lint": "cargo clippy -- -D warnings && (swiftlint lint ios/ 2>/dev/null || (command -v swiftlint >/dev/null 2>&1 || echo 'Note: swiftlint not installed. Install with: brew install swiftlint')) && pnpm lint:kotlin",
59
+ "lint:rust": "cargo clippy -- -D warnings",
60
+ "lint:swift": "swiftlint lint ios/ || (command -v swiftlint >/dev/null 2>&1 || echo 'Note: swiftlint not installed. Install with: brew install swiftlint')",
61
+ "lint:kotlin": "ktlint 'android/src/**/*.kt'"
62
+ }
63
+ }