diff --git a/.changes/config.json b/.changes/config.json
index 70ddfdd58..d9cf7f677 100644
--- a/.changes/config.json
+++ b/.changes/config.json
@@ -33,15 +33,6 @@
}
},
"packages": {
- "authenticator": {
- "path": "./plugins/authenticator",
- "manager": "rust-disabled"
- },
- "authenticator-js": {
- "path": "./plugins/authenticator",
- "manager": "javascript-disabled"
- },
-
"autostart": {
"path": "./plugins/autostart",
"manager": "rust-disabled"
diff --git a/.github/workflows/covector-version-or-publish.yml b/.github/workflows/covector-version-or-publish.yml
index 61498f3d5..d5b04f819 100644
--- a/.github/workflows/covector-version-or-publish.yml
+++ b/.github/workflows/covector-version-or-publish.yml
@@ -29,10 +29,10 @@ jobs:
version: 9.x.x
run_install: true
- - name: install webkit2gtk and libudev for [authenticator]
+ - name: install webkit2gtk
run: |
sudo apt-get update
- sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libudev-dev
+ sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev
- name: cargo login
run: cargo login ${{ secrets.ORG_CRATES_IO_TOKEN }}
diff --git a/.github/workflows/lint-rust.yml b/.github/workflows/lint-rust.yml
index f724e8386..014cfd075 100644
--- a/.github/workflows/lint-rust.yml
+++ b/.github/workflows/lint-rust.yml
@@ -31,10 +31,10 @@ jobs:
steps:
- uses: actions/checkout@v3
- - name: install webkit2gtk and libudev for [authenticator]
+ - name: install webkit2gtk
run: |
sudo apt-get update
- sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libudev-dev
+ sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev
- name: Install clippy with stable toolchain
uses: dtolnay/rust-toolchain@stable
diff --git a/.github/workflows/msrv-check.yml b/.github/workflows/msrv-check.yml
index 3e8acb3dc..9370fe12a 100644
--- a/.github/workflows/msrv-check.yml
+++ b/.github/workflows/msrv-check.yml
@@ -33,10 +33,10 @@ jobs:
steps:
- uses: actions/checkout@v3
- - name: install webkit2gtk and libudev for [authenticator]
+ - name: install webkit2gtk
run: |
sudo apt-get update
- sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libudev-dev
+ sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev
- uses: dtolnay/rust-toolchain@1.67.0
diff --git a/Cargo.lock b/Cargo.lock
index b251aeac0..ca84701a9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -330,23 +330,6 @@ version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3"
-[[package]]
-name = "authenticator"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08cee7a0952628fde958e149507c2bb321ab4fccfafd225da0b20adc956ef88a"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation",
- "devd-rs",
- "libc",
- "libudev",
- "log",
- "rand 0.7.3",
- "runloop",
- "winapi",
-]
-
[[package]]
name = "auto-launch"
version = "0.5.0"
@@ -670,10 +653,8 @@ checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [
"android-tzdata",
"iana-time-zone",
- "js-sys",
"num-traits",
"serde",
- "wasm-bindgen",
"windows-targets 0.48.1",
]
@@ -1040,16 +1021,6 @@ dependencies = [
"syn 1.0.109",
]
-[[package]]
-name = "devd-rs"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9313f104b590510b46fc01c0a324fc76505c13871454d3c48490468d04c8d395"
-dependencies = [
- "libc",
- "nom",
-]
-
[[package]]
name = "digest"
version = "0.9.0"
@@ -2475,26 +2446,6 @@ dependencies = [
"vcpkg",
]
-[[package]]
-name = "libudev"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe"
-dependencies = [
- "libc",
- "libudev-sys",
-]
-
-[[package]]
-name = "libudev-sys"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
-dependencies = [
- "libc",
- "pkg-config",
-]
-
[[package]]
name = "line-wrap"
version = "0.1.1"
@@ -3721,12 +3672,6 @@ dependencies = [
"zeroize",
]
-[[package]]
-name = "runloop"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
-
[[package]]
name = "rust-argon2"
version = "1.0.0"
@@ -4861,27 +4806,6 @@ dependencies = [
"tauri-utils",
]
-[[package]]
-name = "tauri-plugin-authenticator"
-version = "0.0.0"
-dependencies = [
- "authenticator",
- "base64 0.22.0",
- "byteorder",
- "bytes",
- "chrono",
- "log",
- "once_cell",
- "openssl",
- "rand 0.8.5",
- "rusty-fork",
- "serde",
- "serde_json",
- "sha2 0.10.7",
- "tauri",
- "thiserror",
-]
-
[[package]]
name = "tauri-plugin-autostart"
version = "0.0.0"
diff --git a/Cargo.toml b/Cargo.toml
index 7a2d143da..ad325cb87 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,6 @@
[workspace]
# Listed without globs to prevent issues with renovate's baseBranches config.
members = [
- "plugins/authenticator",
"plugins/autostart",
"plugins/fs-extra",
"plugins/fs-watch",
diff --git a/README.md b/README.md
index 6c765f767..932e7b1d9 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,6 @@
| | | Win | Mac | Lin | iOS | And |
| ------------------------------------------ | --------------------------------------------------------- | --- | --- | --- | --- | --- |
-| [authenticator](plugins/authenticator) | Interface with hardware security keys. | ✅ | ✅ | ✅ | ? | ? |
| [autostart](plugins/autostart) | Automatically launch your app at system startup. | ✅ | ✅ | ✅ | ? | ? |
| [fs-extra](plugins/fs-extra) | File system methods that aren't included in the core API. | ✅ | ✅ | ✅ | ? | ? |
| [fs-watch](plugins/fs-watch) | Watch the filesystem for changes. | ✅ | ✅ | ✅ | ? | ? |
diff --git a/plugins/authenticator/.gitignore b/plugins/authenticator/.gitignore
deleted file mode 100644
index b512c09d4..000000000
--- a/plugins/authenticator/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules
\ No newline at end of file
diff --git a/plugins/authenticator/Cargo.toml b/plugins/authenticator/Cargo.toml
deleted file mode 100644
index e7cdc77b6..000000000
--- a/plugins/authenticator/Cargo.toml
+++ /dev/null
@@ -1,29 +0,0 @@
-[package]
-name = "tauri-plugin-authenticator"
-version = "0.0.0"
-description = "Use hardware security-keys in your Tauri App."
-authors = { workspace = true }
-license = { workspace = true }
-edition = { workspace = true }
-rust-version = { workspace = true }
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-serde = { workspace = true }
-serde_json = { workspace = true }
-tauri = { workspace = true }
-log = { workspace = true }
-thiserror = { workspace = true }
-authenticator = "0.3.1"
-once_cell = "1"
-sha2 = "0.10"
-base64 = "0.22"
-chrono = "0.4"
-bytes = "1"
-byteorder = "1"
-openssl = "0.10"
-
-[dev-dependencies]
-rand = "0.8"
-rusty-fork = "0.3"
diff --git a/plugins/authenticator/LICENSE.spdx b/plugins/authenticator/LICENSE.spdx
deleted file mode 100644
index cdd0df5ad..000000000
--- a/plugins/authenticator/LICENSE.spdx
+++ /dev/null
@@ -1,20 +0,0 @@
-SPDXVersion: SPDX-2.1
-DataLicense: CC0-1.0
-PackageName: tauri
-DataFormat: SPDXRef-1
-PackageSupplier: Organization: The Tauri Programme in the Commons Conservancy
-PackageHomePage: https://tauri.app
-PackageLicenseDeclared: Apache-2.0
-PackageLicenseDeclared: MIT
-PackageCopyrightText: 2019-2022, The Tauri Programme in the Commons Conservancy
-PackageSummary: Tauri is a rust project that enables developers to make secure
-and small desktop applications using a web frontend.
-
-PackageComment: The package includes the following libraries; see
-Relationship information.
-
-Created: 2019-05-20T09:00:00Z
-PackageDownloadLocation: git://github.com/tauri-apps/tauri
-PackageDownloadLocation: git+https://github.com/tauri-apps/tauri.git
-PackageDownloadLocation: git+ssh://github.com/tauri-apps/tauri.git
-Creator: Person: Daniel Thompson-Yvetot
\ No newline at end of file
diff --git a/plugins/authenticator/LICENSE_APACHE-2.0 b/plugins/authenticator/LICENSE_APACHE-2.0
deleted file mode 100644
index 4947287f7..000000000
--- a/plugins/authenticator/LICENSE_APACHE-2.0
+++ /dev/null
@@ -1,177 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/plugins/authenticator/LICENSE_MIT b/plugins/authenticator/LICENSE_MIT
deleted file mode 100644
index 4d7547256..000000000
--- a/plugins/authenticator/LICENSE_MIT
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 - Present Tauri Apps Contributors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
diff --git a/plugins/authenticator/README.md b/plugins/authenticator/README.md
deleted file mode 100644
index 6095a5a4c..000000000
--- a/plugins/authenticator/README.md
+++ /dev/null
@@ -1,126 +0,0 @@
-![plugin-authenticator](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/authenticator/banner.png)
-
-Use hardware security-keys in your Tauri App.
-
-## Install
-
-_This plugin requires a Rust version of at least **1.67**_
-
-There are three general methods of installation that we can recommend.
-
-1. Use crates.io and npm (easiest and requires you to trust that our publishing pipeline worked)
-2. Pull sources directly from Github using git tags / revision hashes (most secure)
-3. Git submodule install this repo in your tauri project and then use the file protocol to ingest the source (most secure, but inconvenient to use)
-
-Install the authenticator plugin by adding the following lines to your `Cargo.toml` file:
-
-`src-tauri/Cargo.toml`
-
-```toml
-[dependencies]
-tauri-plugin-authenticator = "0.1"
-# or through git
-tauri-plugin-authenticator = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
-```
-
-You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
-
-> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use.
-
-```sh
-pnpm add https://github.com/tauri-apps/tauri-plugin-authenticator#v1
-# or
-npm add https://github.com/tauri-apps/tauri-plugin-authenticator#v1
-# or
-yarn add https://github.com/tauri-apps/tauri-plugin-authenticator#v1
-```
-
-## Usage
-
-First, you need to register the authenticator plugin with Tauri:
-
-`src-tauri/src/main.rs`
-
-```rust
-fn main() {
- tauri::Builder::default()
- .plugin(tauri_plugin_authenticator::init())
- .run(tauri::generate_context!())
- .expect("error while running tauri application");
-}
-```
-
-Afterwards, all the plugin's APIs are available through the JavaScript guest bindings:
-
-```javascript
-import { Authenticator } from "tauri-plugin-authenticator-api";
-
-const auth = new Authenticator();
-auth.init(); // initialize transports
-
-// generate a 32-bytes long random challenge
-const arr = new Uint32Array(32);
-window.crypto.getRandomValues(arr);
-const b64 = btoa(String.fromCharCode.apply(null, arr));
-// web-safe base64
-const challenge = b64.replace(/\+/g, "-").replace(/\//g, "_");
-
-const domain = "https://tauri.app";
-
-// attempt to register with the security key
-const json = await auth.register(challenge, domain);
-const registerResult = JSON.parse(json);
-
-// verify the registration was successful
-const r2 = await auth.verifyRegistration(
- challenge,
- app,
- registerResult.registerData,
- registerResult.clientData,
-);
-const j2 = JSON.parse(r2);
-
-// sign some data
-const json = await auth.sign(challenge, app, keyHandle);
-const signData = JSON.parse(json);
-
-// verify the signature again
-const counter = await auth.verifySignature(
- challenge,
- app,
- signData.signData,
- clientData,
- keyHandle,
- pubkey,
-);
-
-if (counter && counter > 0) {
- console.log("SUCCESS!");
-}
-```
-
-## Contributing
-
-PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
-
-## Partners
-
-
-
-
-
-
-
-
- |
-
-
-
-
-For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri).
-
-## License
-
-Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy.
-
-MIT or MIT/Apache 2.0 where applicable.
diff --git a/plugins/authenticator/banner.png b/plugins/authenticator/banner.png
deleted file mode 100644
index 405dc6018..000000000
Binary files a/plugins/authenticator/banner.png and /dev/null differ
diff --git a/plugins/authenticator/guest-js/index.ts b/plugins/authenticator/guest-js/index.ts
deleted file mode 100644
index ab3be8b9c..000000000
--- a/plugins/authenticator/guest-js/index.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { invoke } from "@tauri-apps/api/tauri";
-
-export class Authenticator {
- async init(): Promise {
- return await invoke("plugin:authenticator|init_auth");
- }
-
- async register(challenge: string, application: string): Promise {
- return await invoke("plugin:authenticator|register", {
- timeout: 10000,
- challenge,
- application,
- });
- }
-
- async verifyRegistration(
- challenge: string,
- application: string,
- registerData: string,
- clientData: string,
- ): Promise {
- return await invoke("plugin:authenticator|verify_registration", {
- challenge,
- application,
- registerData,
- clientData,
- });
- }
-
- async sign(
- challenge: string,
- application: string,
- keyHandle: string,
- ): Promise {
- return await invoke("plugin:authenticator|sign", {
- timeout: 10000,
- challenge,
- application,
- keyHandle,
- });
- }
-
- async verifySignature(
- challenge: string,
- application: string,
- signData: string,
- clientData: string,
- keyHandle: string,
- pubkey: string,
- ): Promise {
- return await invoke("plugin:authenticator|verify_signature", {
- challenge,
- application,
- signData,
- clientData,
- keyHandle,
- pubkey,
- });
- }
-}
diff --git a/plugins/authenticator/package.json b/plugins/authenticator/package.json
deleted file mode 100644
index 1f75b6dda..000000000
--- a/plugins/authenticator/package.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "name": "tauri-plugin-authenticator-api",
- "version": "0.0.0",
- "description": "Use hardware security-keys in your Tauri App.",
- "license": "MIT or APACHE-2.0",
- "authors": [
- "Tauri Programme within The Commons Conservancy"
- ],
- "type": "module",
- "browser": "dist-js/index.min.js",
- "module": "dist-js/index.mjs",
- "types": "dist-js/index.d.ts",
- "exports": {
- "import": "./dist-js/index.mjs",
- "types": "./dist-js/index.d.ts",
- "browser": "./dist-js/index.min.js"
- },
- "scripts": {
- "build": "rollup -c"
- },
- "files": [
- "dist-js",
- "!dist-js/**/*.map",
- "README.md",
- "LICENSE"
- ],
- "devDependencies": {
- "tslib": "2.7.0"
- },
- "dependencies": {
- "@tauri-apps/api": "1.6.0"
- }
-}
diff --git a/plugins/authenticator/rollup.config.mjs b/plugins/authenticator/rollup.config.mjs
deleted file mode 100644
index 99a3dd319..000000000
--- a/plugins/authenticator/rollup.config.mjs
+++ /dev/null
@@ -1,11 +0,0 @@
-import { readFileSync } from "fs";
-
-import { createConfig } from "../../shared/rollup.config.mjs";
-
-export default createConfig({
- input: "guest-js/index.ts",
- pkg: JSON.parse(
- readFileSync(new URL("./package.json", import.meta.url), "utf8"),
- ),
- external: [/^@tauri-apps\/api/],
-});
diff --git a/plugins/authenticator/src/auth.rs b/plugins/authenticator/src/auth.rs
deleted file mode 100644
index c334173d4..000000000
--- a/plugins/authenticator/src/auth.rs
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2021 Tauri Programme within The Commons Conservancy
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-use authenticator::{
- authenticatorservice::AuthenticatorService, statecallback::StateCallback,
- AuthenticatorTransports, KeyHandle, RegisterFlags, SignFlags, StatusUpdate,
-};
-use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
-use once_cell::sync::Lazy;
-use serde::Serialize;
-use sha2::{Digest, Sha256};
-use std::io;
-use std::sync::mpsc::channel;
-use std::{convert::Into, sync::Mutex};
-
-static MANAGER: Lazy> = Lazy::new(|| {
- let manager = AuthenticatorService::new().expect("The auth service should initialize safely");
- Mutex::new(manager)
-});
-
-pub fn init_usb() {
- let mut manager = MANAGER.lock().unwrap();
- // theres also "add_detected_transports()" in the docs?
- manager.add_u2f_usb_hid_platform_transports();
-}
-
-#[derive(Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct Registration {
- pub key_handle: String,
- pub pubkey: String,
- pub register_data: String,
- pub client_data: String,
-}
-
-pub fn register(application: String, timeout: u64, challenge: String) -> crate::Result {
- let (chall_bytes, app_bytes, client_data_string) =
- format_client_data(application.as_str(), challenge.as_str());
-
- // log the status rx?
- let (status_tx, _status_rx) = channel::();
-
- let mut manager = MANAGER.lock().unwrap();
-
- let (register_tx, register_rx) = channel();
- let callback = StateCallback::new(Box::new(move |rv| {
- register_tx.send(rv).unwrap();
- }));
-
- let res = manager.register(
- RegisterFlags::empty(),
- timeout,
- chall_bytes,
- app_bytes,
- vec![],
- status_tx,
- callback,
- );
-
- match res {
- Ok(_r) => {
- let register_result = register_rx
- .recv()
- .expect("Problem receiving, unable to continue");
-
- if let Err(e) = register_result {
- return Err(e.into());
- }
-
- let (register_data, device_info) = register_result.unwrap(); // error already has been checked
-
- // println!("Register result: {}", base64::encode(®ister_data));
- println!("Device info: {}", &device_info);
-
- let (key_handle, public_key) =
- _u2f_get_key_handle_and_public_key_from_register_response(®ister_data).unwrap();
- let key_handle_base64 = URL_SAFE_NO_PAD.encode(key_handle);
- let public_key_base64 = URL_SAFE_NO_PAD.encode(public_key);
- let register_data_base64 = URL_SAFE_NO_PAD.encode(®ister_data);
- println!("Key Handle: {}", &key_handle_base64);
- println!("Public Key: {}", &public_key_base64);
-
- // Ok(base64::encode(®ister_data))
- // Ok(key_handle_base64)
- let res = serde_json::to_string(&Registration {
- key_handle: key_handle_base64,
- pubkey: public_key_base64,
- register_data: register_data_base64,
- client_data: client_data_string,
- })?;
- Ok(res)
- }
- Err(e) => Err(e.into()),
- }
-}
-
-#[derive(Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct Signature {
- pub key_handle: String,
- pub sign_data: String,
-}
-
-pub fn sign(
- application: String,
- timeout: u64,
- challenge: String,
- key_handle: String,
-) -> crate::Result {
- let credential = match URL_SAFE_NO_PAD.decode(key_handle) {
- Ok(v) => v,
- Err(e) => {
- return Err(e.into());
- }
- };
- let key_handle = KeyHandle {
- credential,
- transports: AuthenticatorTransports::empty(),
- };
-
- let (chall_bytes, app_bytes, _) = format_client_data(application.as_str(), challenge.as_str());
-
- let (sign_tx, sign_rx) = channel();
- let callback = StateCallback::new(Box::new(move |rv| {
- sign_tx.send(rv).unwrap();
- }));
-
- // log the status rx?
- let (status_tx, _status_rx) = channel::();
-
- let mut manager = MANAGER.lock().unwrap();
-
- let res = manager.sign(
- SignFlags::empty(),
- timeout,
- chall_bytes,
- vec![app_bytes],
- vec![key_handle],
- status_tx,
- callback,
- );
- match res {
- Ok(_v) => {
- let sign_result = sign_rx
- .recv()
- .expect("Problem receiving, unable to continue");
-
- if let Err(e) = sign_result {
- return Err(e.into());
- }
-
- let (_, handle_used, sign_data, device_info) = sign_result.unwrap();
-
- let sig = URL_SAFE_NO_PAD.encode(sign_data);
-
- println!("Sign result: {sig}");
- println!("Key handle used: {}", URL_SAFE_NO_PAD.encode(&handle_used));
- println!("Device info: {}", &device_info);
- println!("Done.");
-
- let res = serde_json::to_string(&Signature {
- sign_data: sig,
- key_handle: URL_SAFE_NO_PAD.encode(&handle_used),
- })?;
- Ok(res)
- }
- Err(e) => Err(e.into()),
- }
-}
-
-fn format_client_data(application: &str, challenge: &str) -> (Vec, Vec, String) {
- let d =
- format!(r#"{{"challenge": "{challenge}", "version": "U2F_V2", "appId": "{application}"}}"#);
- let mut challenge = Sha256::new();
- challenge.update(d.as_bytes());
- let chall_bytes = challenge.finalize().to_vec();
-
- let mut app = Sha256::new();
- app.update(application.as_bytes());
- let app_bytes = app.finalize().to_vec();
-
- (chall_bytes, app_bytes, d)
-}
-
-fn _u2f_get_key_handle_and_public_key_from_register_response(
- register_response: &[u8],
-) -> io::Result<(Vec, Vec)> {
- if register_response[0] != 0x05 {
- return Err(io::Error::new(
- io::ErrorKind::InvalidData,
- "Reserved byte not set correctly",
- ));
- }
-
- // 1: reserved
- // 65: public key
- // 1: key handle length
- // key handle
- // x.509 cert
- // sig
-
- let key_handle_len = register_response[66] as usize;
- let mut public_key = register_response.to_owned();
- let mut key_handle = public_key.split_off(67);
- let _attestation = key_handle.split_off(key_handle_len);
-
- // remove fist (reserved) and last (handle len) bytes
- let pk: Vec = public_key[1..public_key.len() - 1].to_vec();
-
- Ok((key_handle, pk))
-}
diff --git a/plugins/authenticator/src/error.rs b/plugins/authenticator/src/error.rs
deleted file mode 100644
index db731e8f8..000000000
--- a/plugins/authenticator/src/error.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use serde::{Serialize, Serializer};
-
-#[derive(Debug, thiserror::Error)]
-pub enum Error {
- #[error(transparent)]
- Base64Decode(#[from] base64::DecodeError),
- #[error(transparent)]
- JSON(#[from] serde_json::Error),
- #[error(transparent)]
- U2F(#[from] crate::u2f_crate::u2ferror::U2fError),
- #[error(transparent)]
- Auth(#[from] authenticator::errors::AuthenticatorError),
-}
-
-impl Serialize for Error {
- fn serialize(&self, serializer: S) -> std::result::Result
- where
- S: Serializer,
- {
- serializer.serialize_str(self.to_string().as_ref())
- }
-}
diff --git a/plugins/authenticator/src/lib.rs b/plugins/authenticator/src/lib.rs
deleted file mode 100644
index 36ed02289..000000000
--- a/plugins/authenticator/src/lib.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2021 Tauri Programme within The Commons Conservancy
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-mod auth;
-mod error;
-mod u2f;
-mod u2f_crate;
-
-use tauri::{
- plugin::{Builder as PluginBuilder, TauriPlugin},
- Runtime,
-};
-
-pub use error::Error;
-type Result = std::result::Result;
-
-#[tauri::command]
-fn init_auth() {
- auth::init_usb();
-}
-
-#[tauri::command]
-fn register(timeout: u64, challenge: String, application: String) -> crate::Result {
- auth::register(application, timeout, challenge)
-}
-
-#[tauri::command]
-fn verify_registration(
- challenge: String,
- application: String,
- register_data: String,
- client_data: String,
-) -> crate::Result {
- u2f::verify_registration(application, challenge, register_data, client_data)
-}
-
-#[tauri::command]
-fn sign(
- timeout: u64,
- challenge: String,
- application: String,
- key_handle: String,
-) -> crate::Result {
- auth::sign(application, timeout, challenge, key_handle)
-}
-
-#[tauri::command]
-fn verify_signature(
- challenge: String,
- application: String,
- sign_data: String,
- client_data: String,
- key_handle: String,
- pubkey: String,
-) -> crate::Result {
- u2f::verify_signature(
- application,
- challenge,
- sign_data,
- client_data,
- key_handle,
- pubkey,
- )
-}
-
-pub fn init() -> TauriPlugin {
- PluginBuilder::new("authenticator")
- .invoke_handler(tauri::generate_handler![
- init_auth,
- register,
- verify_registration,
- sign,
- verify_signature
- ])
- .build()
-}
diff --git a/plugins/authenticator/src/u2f.rs b/plugins/authenticator/src/u2f.rs
deleted file mode 100644
index 8a443b168..000000000
--- a/plugins/authenticator/src/u2f.rs
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2021 Tauri Programme within The Commons Conservancy
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-use crate::u2f_crate::messages::*;
-use crate::u2f_crate::protocol::*;
-use crate::u2f_crate::register::*;
-use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
-use chrono::prelude::*;
-use serde::Serialize;
-use std::convert::Into;
-
-static VERSION: &str = "U2F_V2";
-
-pub fn make_challenge(app_id: &str, challenge_bytes: Vec) -> Challenge {
- let utc: DateTime = Utc::now();
- Challenge {
- challenge: URL_SAFE_NO_PAD.encode(challenge_bytes),
- timestamp: format!("{utc:?}"),
- app_id: app_id.to_string(),
- }
-}
-
-#[derive(Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct RegistrationVerification {
- pub key_handle: String,
- pub pubkey: String,
- pub device_name: Option,
-}
-
-pub fn verify_registration(
- app_id: String,
- challenge: String,
- register_data: String,
- client_data: String,
-) -> crate::Result {
- let challenge_bytes = URL_SAFE_NO_PAD.decode(challenge)?;
- let challenge = make_challenge(&app_id, challenge_bytes);
- let client_data_bytes: Vec = client_data.as_bytes().into();
- let client_data_base64 = URL_SAFE_NO_PAD.encode(client_data_bytes);
- let client = U2f::new(app_id);
- match client.register_response(
- challenge,
- RegisterResponse {
- registration_data: register_data,
- client_data: client_data_base64,
- version: VERSION.to_string(),
- },
- ) {
- Ok(v) => {
- let rv = RegistrationVerification {
- key_handle: URL_SAFE_NO_PAD.encode(&v.key_handle),
- pubkey: URL_SAFE_NO_PAD.encode(&v.pub_key),
- device_name: v.device_name,
- };
- Ok(serde_json::to_string(&rv)?)
- }
- Err(e) => Err(e.into()),
- }
-}
-
-#[derive(Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct SignatureVerification {
- pub counter: u8,
-}
-
-pub fn verify_signature(
- app_id: String,
- challenge: String,
- sign_data: String,
- client_data: String,
- key_handle: String,
- pub_key: String,
-) -> crate::Result {
- let challenge_bytes = URL_SAFE_NO_PAD.decode(challenge)?;
- let chal = make_challenge(&app_id, challenge_bytes);
- let client_data_bytes: Vec = client_data.as_bytes().into();
- let client_data_base64 = URL_SAFE_NO_PAD.encode(client_data_bytes);
- let key_handle_bytes = URL_SAFE_NO_PAD.decode(&key_handle)?;
- let pubkey_bytes = URL_SAFE_NO_PAD.decode(pub_key)?;
- let client = U2f::new(app_id);
- let mut _counter: u32 = 0;
- match client.sign_response(
- chal,
- Registration {
- // here only needs pubkey and keyhandle
- key_handle: key_handle_bytes,
- pub_key: pubkey_bytes,
- attestation_cert: None,
- device_name: None,
- },
- SignResponse {
- // here needs client data and sig data and key_handle
- signature_data: sign_data,
- client_data: client_data_base64,
- key_handle,
- },
- _counter,
- ) {
- Ok(v) => Ok(v),
- Err(e) => Err(e.into()),
- }
-}
diff --git a/plugins/authenticator/src/u2f_crate/LICENSE b/plugins/authenticator/src/u2f_crate/LICENSE
deleted file mode 100644
index d26d5f6c0..000000000
--- a/plugins/authenticator/src/u2f_crate/LICENSE
+++ /dev/null
@@ -1,8 +0,0 @@
-Copyright (c) 2017
-
-Licensed under either of
-
- * Apache License, Version 2.0, (http://www.apache.org/licenses/LICENSE-2.0)
- * MIT license (http://opensource.org/licenses/MIT)
-
-at your option.
\ No newline at end of file
diff --git a/plugins/authenticator/src/u2f_crate/authorization.rs b/plugins/authenticator/src/u2f_crate/authorization.rs
deleted file mode 100644
index 35a1a3e1e..000000000
--- a/plugins/authenticator/src/u2f_crate/authorization.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2021 Flavio Oliveira
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-use bytes::{Buf, BufMut};
-use openssl::sha::sha256;
-use serde::Serialize;
-use std::io::Cursor;
-
-use crate::u2f_crate::u2ferror::U2fError;
-
-/// The `Result` type used in this crate.
-type Result = ::std::result::Result;
-
-#[derive(Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct Authorization {
- pub counter: u32,
- pub user_presence: bool,
-}
-
-pub fn parse_sign_response(
- app_id: String,
- client_data: Vec,
- public_key: Vec,
- sign_data: Vec,
-) -> Result {
- if sign_data.len() <= 5 {
- return Err(U2fError::InvalidSignatureData);
- }
-
- let user_presence_flag = &sign_data[0];
- let counter = &sign_data[1..=4];
- let signature = &sign_data[5..];
-
- // Let's build the msg to verify the signature
- let app_id_hash = sha256(&app_id.into_bytes());
- let client_data_hash = sha256(&client_data[..]);
-
- let mut msg = vec![];
- msg.put(app_id_hash.as_ref());
- msg.put_u8(*user_presence_flag);
- msg.put(counter);
- msg.put(client_data_hash.as_ref());
-
- let public_key = super::crypto::NISTP256Key::from_bytes(&public_key)?;
-
- // The signature is to be verified by the relying party using the public key obtained during registration.
- let verified = public_key.verify_signature(signature, msg.as_ref())?;
- if !verified {
- return Err(U2fError::BadSignature);
- }
-
- let authorization = Authorization {
- counter: get_counter(counter),
- user_presence: true,
- };
-
- Ok(authorization)
-}
-
-fn get_counter(counter: &[u8]) -> u32 {
- let mut buf = Cursor::new(counter);
- buf.get_u32()
-}
diff --git a/plugins/authenticator/src/u2f_crate/crypto.rs b/plugins/authenticator/src/u2f_crate/crypto.rs
deleted file mode 100644
index 323798054..000000000
--- a/plugins/authenticator/src/u2f_crate/crypto.rs
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2021 Flavio Oliveira
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-//! Cryptographic operation wrapper for Webauthn. This module exists to
-//! allow ease of auditing, safe operation wrappers for the webauthn library,
-//! and cryptographic provider abstraction. This module currently uses OpenSSL
-//! as the cryptographic primitive provider.
-
-// Source can be found here: https://github.com/Firstyear/webauthn-rs/blob/master/src/crypto.rs
-
-#![allow(non_camel_case_types)]
-
-use openssl::{bn, ec, hash, nid, sign, x509};
-use std::convert::TryFrom;
-
-// use super::constants::*;
-use crate::u2f_crate::u2ferror::U2fError;
-use openssl::pkey::Public;
-
-// use super::proto::*;
-
-// Why OpenSSL over another rust crate?
-// - Well, the openssl crate allows us to reconstruct a public key from the
-// x/y group coords, where most others want a pkcs formatted structure. As
-// a result, it's easiest to use openssl as it gives us exactly what we need
-// for these operations, and despite it's many challenges as a library, it
-// has resources and investment into it's maintenance, so we can a least
-// assert a higher level of confidence in it that .
-
-// Object({Integer(-3): Bytes([48, 185, 178, 204, 113, 186, 105, 138, 190, 33, 160, 46, 131, 253, 100, 177, 91, 243, 126, 128, 245, 119, 209, 59, 186, 41, 215, 196, 24, 222, 46, 102]), Integer(-2): Bytes([158, 212, 171, 234, 165, 197, 86, 55, 141, 122, 253, 6, 92, 242, 242, 114, 158, 221, 238, 163, 127, 214, 120, 157, 145, 226, 232, 250, 144, 150, 218, 138]), Integer(-1): U64(1), Integer(1): U64(2), Integer(3): I64(-7)})
-//
-
-/// An X509PublicKey. This is what is otherwise known as a public certificate
-/// which comprises a public key and other signed metadata related to the issuer
-/// of the key.
-pub struct X509PublicKey {
- pubk: x509::X509,
-}
-
-impl std::fmt::Debug for X509PublicKey {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- write!(f, "X509PublicKey")
- }
-}
-
-impl TryFrom<&[u8]> for X509PublicKey {
- type Error = U2fError;
-
- // Must be DER bytes. If you have PEM, base64decode first!
- fn try_from(d: &[u8]) -> Result {
- let pubk = x509::X509::from_der(d)?;
- Ok(X509PublicKey { pubk })
- }
-}
-
-impl X509PublicKey {
- pub(crate) fn common_name(&self) -> Option {
- let cert = &self.pubk;
-
- let subject = cert.subject_name();
- let common = subject
- .entries_by_nid(openssl::nid::Nid::COMMONNAME)
- .next()
- .map(|b| b.data().as_slice());
-
- if let Some(common) = common {
- std::str::from_utf8(common).ok().map(|s| s.to_string())
- } else {
- None
- }
- }
-
- pub(crate) fn is_secp256r1(&self) -> Result {
- // Can we get the public key?
- let pk = self.pubk.public_key()?;
-
- let ec_key = pk.ec_key()?;
-
- ec_key.check_key()?;
-
- let ec_grpref = ec_key.group();
-
- let ec_curve = ec_grpref.curve_name().ok_or(U2fError::OpenSSLNoCurveName)?;
-
- Ok(ec_curve == nid::Nid::X9_62_PRIME256V1)
- }
-
- pub(crate) fn verify_signature(
- &self,
- signature: &[u8],
- verification_data: &[u8],
- ) -> Result {
- let pkey = self.pubk.public_key()?;
-
- // TODO: Should this determine the hash type from the x509 cert? Or other?
- let mut verifier = sign::Verifier::new(hash::MessageDigest::sha256(), &pkey)?;
- verifier.update(verification_data)?;
- Ok(verifier.verify(signature)?)
- }
-}
-
-pub struct NISTP256Key {
- /// The key's public X coordinate.
- pub x: [u8; 32],
- /// The key's public Y coordinate.
- pub y: [u8; 32],
-}
-
-impl NISTP256Key {
- pub fn from_bytes(public_key_bytes: &[u8]) -> Result {
- if public_key_bytes.len() != 65 {
- return Err(U2fError::InvalidPublicKey);
- }
-
- if public_key_bytes[0] != 0x04 {
- return Err(U2fError::InvalidPublicKey);
- }
-
- let mut x: [u8; 32] = Default::default();
- x.copy_from_slice(&public_key_bytes[1..=32]);
-
- let mut y: [u8; 32] = Default::default();
- y.copy_from_slice(&public_key_bytes[33..=64]);
-
- Ok(NISTP256Key { x, y })
- }
-
- fn get_key(&self) -> Result, U2fError> {
- let ec_group = ec::EcGroup::from_curve_name(openssl::nid::Nid::X9_62_PRIME256V1)?;
-
- let xbn = bn::BigNum::from_slice(&self.x)?;
- let ybn = bn::BigNum::from_slice(&self.y)?;
-
- let ec_key = openssl::ec::EcKey::from_public_key_affine_coordinates(&ec_group, &xbn, &ybn)?;
-
- // Validate the key is sound. IIRC this actually checks the values
- // are correctly on the curve as specified
- ec_key.check_key()?;
-
- Ok(ec_key)
- }
-
- pub fn verify_signature(
- &self,
- signature: &[u8],
- verification_data: &[u8],
- ) -> Result {
- let pkey = self.get_key()?;
-
- let signature = openssl::ecdsa::EcdsaSig::from_der(signature)?;
- let hash = openssl::sha::sha256(verification_data);
-
- Ok(signature.verify(hash.as_ref(), &pkey)?)
- }
-}
diff --git a/plugins/authenticator/src/u2f_crate/messages.rs b/plugins/authenticator/src/u2f_crate/messages.rs
deleted file mode 100644
index 8e0cea71c..000000000
--- a/plugins/authenticator/src/u2f_crate/messages.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2021 Flavio Oliveira
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-// As defined by FIDO U2F Javascript API.
-// https://fidoalliance.org/specs/fido-u2f-v1.0-nfc-bt-amendment-20150514/fido-u2f-javascript-api.html#registration
-
-use serde::{Deserialize, Serialize};
-
-#[derive(Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct U2fRegisterRequest {
- pub app_id: String,
- pub register_requests: Vec,
- pub registered_keys: Vec,
-}
-
-#[derive(Serialize)]
-pub struct RegisterRequest {
- pub version: String,
- pub challenge: String,
-}
-
-#[derive(Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct RegisteredKey {
- pub version: String,
- pub key_handle: Option,
- pub app_id: String,
-}
-
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct RegisterResponse {
- pub registration_data: String,
- #[allow(dead_code)]
- pub version: String,
- pub client_data: String,
-}
-
-#[derive(Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct U2fSignRequest {
- pub app_id: String,
- pub challenge: String,
- pub registered_keys: Vec,
-}
-
-#[derive(Clone, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct SignResponse {
- pub key_handle: String,
- pub signature_data: String,
- pub client_data: String,
-}
diff --git a/plugins/authenticator/src/u2f_crate/mod.rs b/plugins/authenticator/src/u2f_crate/mod.rs
deleted file mode 100644
index 0aaebf6ff..000000000
--- a/plugins/authenticator/src/u2f_crate/mod.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2021 Flavio Oliveira
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-mod util;
-
-pub mod authorization;
-mod crypto;
-pub mod messages;
-pub mod protocol;
-pub mod register;
-pub mod u2ferror;
diff --git a/plugins/authenticator/src/u2f_crate/protocol.rs b/plugins/authenticator/src/u2f_crate/protocol.rs
deleted file mode 100644
index fc7343ea1..000000000
--- a/plugins/authenticator/src/u2f_crate/protocol.rs
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2021 Flavio Oliveira
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-use crate::u2f_crate::authorization::*;
-use crate::u2f_crate::messages::*;
-use crate::u2f_crate::register::*;
-use crate::u2f_crate::u2ferror::U2fError;
-use crate::u2f_crate::util::*;
-
-use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
-use chrono::prelude::*;
-use chrono::Duration;
-use serde::{Deserialize, Serialize};
-
-type Result = ::std::result::Result;
-
-#[derive(Clone)]
-pub struct U2f {
- app_id: String,
-}
-
-#[derive(Deserialize, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct Challenge {
- pub app_id: String,
- pub challenge: String,
- pub timestamp: String,
-}
-
-impl Challenge {
- // Not used in this plugin.
- #[allow(dead_code)]
- pub fn new() -> Self {
- Challenge {
- app_id: String::new(),
- challenge: String::new(),
- timestamp: String::new(),
- }
- }
-}
-
-impl U2f {
- // The app ID is a string used to uniquely identify an U2F app
- pub fn new(app_id: String) -> Self {
- U2f { app_id }
- }
-
- // Not used in this plugin.
- #[allow(dead_code)]
- pub fn generate_challenge(&self) -> Result {
- let utc: DateTime = Utc::now();
-
- let challenge_bytes = generate_challenge(32)?;
- let challenge = Challenge {
- challenge: URL_SAFE_NO_PAD.encode(challenge_bytes),
- timestamp: format!("{:?}", utc),
- app_id: self.app_id.clone(),
- };
-
- Ok(challenge.clone())
- }
-
- // Not used in this plugin.
- #[allow(dead_code)]
- pub fn request(
- &self,
- challenge: Challenge,
- registrations: Vec,
- ) -> Result {
- let u2f_request = U2fRegisterRequest {
- app_id: self.app_id.clone(),
- register_requests: self.register_request(challenge),
- registered_keys: self.registered_keys(registrations),
- };
-
- Ok(u2f_request)
- }
-
- fn register_request(&self, challenge: Challenge) -> Vec {
- let mut requests: Vec = vec![];
-
- let request = RegisterRequest {
- version: U2F_V2.into(),
- challenge: challenge.challenge,
- };
- requests.push(request);
-
- requests
- }
-
- pub fn register_response(
- &self,
- challenge: Challenge,
- response: RegisterResponse,
- ) -> Result {
- if expiration(challenge.timestamp) > Duration::seconds(300) {
- return Err(U2fError::ChallengeExpired);
- }
-
- let registration_data: Vec = URL_SAFE_NO_PAD
- .decode(&response.registration_data[..])
- .unwrap();
- let client_data: Vec = URL_SAFE_NO_PAD.decode(&response.client_data[..]).unwrap();
-
- parse_registration(challenge.app_id, client_data, registration_data)
- }
-
- fn registered_keys(&self, registrations: Vec) -> Vec {
- let mut keys: Vec = vec![];
-
- for registration in registrations {
- keys.push(get_registered_key(
- self.app_id.clone(),
- registration.key_handle,
- ));
- }
-
- keys
- }
-
- // Not used in this plugin.
- #[allow(dead_code)]
- pub fn sign_request(
- &self,
- challenge: Challenge,
- registrations: Vec,
- ) -> U2fSignRequest {
- let mut keys: Vec = vec![];
-
- for registration in registrations {
- keys.push(get_registered_key(
- self.app_id.clone(),
- registration.key_handle,
- ));
- }
-
- let signed_request = U2fSignRequest {
- app_id: self.app_id.clone(),
- challenge: URL_SAFE_NO_PAD.encode(challenge.challenge.as_bytes()),
- registered_keys: keys,
- };
-
- signed_request
- }
-
- pub fn sign_response(
- &self,
- challenge: Challenge,
- reg: Registration,
- sign_resp: SignResponse,
- counter: u32,
- ) -> Result {
- if expiration(challenge.timestamp) > Duration::seconds(300) {
- return Err(U2fError::ChallengeExpired);
- }
-
- if sign_resp.key_handle != get_encoded(®.key_handle[..]) {
- return Err(U2fError::WrongKeyHandler);
- }
-
- let client_data: Vec = URL_SAFE_NO_PAD
- .decode(&sign_resp.client_data[..])
- .map_err(|_e| U2fError::InvalidClientData)?;
- let sign_data: Vec = URL_SAFE_NO_PAD
- .decode(&sign_resp.signature_data[..])
- .map_err(|_e| U2fError::InvalidSignatureData)?;
-
- let public_key = reg.pub_key;
-
- let auth = parse_sign_response(
- self.app_id.clone(),
- client_data.clone(),
- public_key,
- sign_data.clone(),
- );
-
- match auth {
- Ok(ref res) => {
- // CounterTooLow is raised when the counter value received from the device is
- // lower than last stored counter value.
- if res.counter < counter {
- Err(U2fError::CounterTooLow)
- } else {
- Ok(res.counter)
- }
- }
- Err(e) => Err(e),
- }
- }
-}
diff --git a/plugins/authenticator/src/u2f_crate/register.rs b/plugins/authenticator/src/u2f_crate/register.rs
deleted file mode 100644
index 3717b0036..000000000
--- a/plugins/authenticator/src/u2f_crate/register.rs
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2021 Flavio Oliveira
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-use byteorder::{BigEndian, ByteOrder};
-use bytes::{BufMut, Bytes};
-use openssl::sha::sha256;
-use serde::Serialize;
-
-use crate::u2f_crate::messages::RegisteredKey;
-use crate::u2f_crate::u2ferror::U2fError;
-use crate::u2f_crate::util::*;
-use std::convert::TryFrom;
-
-/// The `Result` type used in this crate.
-type Result = ::std::result::Result;
-
-// Single enrolment or pairing between an application and a token.
-#[derive(Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct Registration {
- pub key_handle: Vec,
- pub pub_key: Vec,
-
- // AttestationCert can be null for Authenticate requests.
- pub attestation_cert: Option>,
- pub device_name: Option,
-}
-
-pub fn parse_registration(
- app_id: String,
- client_data: Vec,
- registration_data: Vec,
-) -> Result {
- let reserved_byte = registration_data[0];
- if reserved_byte != 0x05 {
- return Err(U2fError::InvalidReservedByte);
- }
-
- let mut mem = Bytes::from(registration_data);
-
- //Start parsing ... advance the reserved byte.
- let _ = mem.split_to(1);
-
- // P-256 NIST elliptic curve
- let public_key = mem.split_to(65);
-
- // Key Handle
- let key_handle_size = mem.split_to(1);
- let key_len = BigEndian::read_uint(&key_handle_size[..], 1);
- let key_handle = mem.split_to(key_len as usize);
-
- // The certificate length needs to be inferred by parsing.
- let cert_len = asn_length(mem.clone()).unwrap();
- let attestation_certificate = mem.split_to(cert_len);
-
- // Remaining data corresponds to the signature
- let signature = mem;
-
- // Let's build the msg to verify the signature
- let app_id_hash = sha256(&app_id.into_bytes());
- let client_data_hash = sha256(&client_data[..]);
-
- let mut msg = vec![0x00]; // A byte reserved for future use [1 byte] with the value 0x00
- msg.put(app_id_hash.as_ref());
- msg.put(client_data_hash.as_ref());
- msg.put(key_handle.clone());
- msg.put(public_key.clone());
-
- // The signature is to be verified by the relying party using the public key certified
- // in the attestation certificate.
- let cerificate_public_key =
- super::crypto::X509PublicKey::try_from(&attestation_certificate[..])?;
-
- if !(cerificate_public_key.is_secp256r1()?) {
- return Err(U2fError::BadCertificate);
- }
-
- let verified = cerificate_public_key.verify_signature(&signature[..], &msg[..])?;
-
- if !verified {
- return Err(U2fError::BadCertificate);
- }
-
- let registration = Registration {
- key_handle: key_handle[..].to_vec(),
- pub_key: public_key[..].to_vec(),
- attestation_cert: Some(attestation_certificate[..].to_vec()),
- device_name: cerificate_public_key.common_name(),
- };
-
- Ok(registration)
-}
-
-pub fn get_registered_key(app_id: String, key_handle: Vec) -> RegisteredKey {
- RegisteredKey {
- app_id,
- version: U2F_V2.into(),
- key_handle: Some(get_encoded(key_handle.as_slice())),
- }
-}
diff --git a/plugins/authenticator/src/u2f_crate/u2ferror.rs b/plugins/authenticator/src/u2f_crate/u2ferror.rs
deleted file mode 100644
index 9ae8fa92e..000000000
--- a/plugins/authenticator/src/u2f_crate/u2ferror.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2021 Flavio Oliveira
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-use thiserror::Error;
-
-#[derive(Debug, Error)]
-pub enum U2fError {
- #[error("ASM1 Decoder error")]
- Asm1DecoderError,
- #[error("Not able to verify signature")]
- BadSignature,
- #[error("Not able to generate random bytes")]
- RandomSecureBytesError,
- #[error("Invalid Reserved Byte")]
- InvalidReservedByte,
- #[error("Challenge Expired")]
- ChallengeExpired,
- #[error("Wrong Key Handler")]
- WrongKeyHandler,
- #[error("Invalid Client Data")]
- InvalidClientData,
- #[error("Invalid Signature Data")]
- InvalidSignatureData,
- #[error("Invalid User Presence Byte")]
- InvalidUserPresenceByte,
- #[error("Failed to parse certificate")]
- BadCertificate,
- #[error("Not Trusted Anchor")]
- NotTrustedAnchor,
- #[error("Counter too low")]
- CounterTooLow,
- #[error("Invalid public key")]
- OpenSSLNoCurveName,
- #[error("OpenSSL no curve name")]
- InvalidPublicKey,
- #[error(transparent)]
- OpenSSLError(#[from] openssl::error::ErrorStack),
-}
diff --git a/plugins/authenticator/src/u2f_crate/util.rs b/plugins/authenticator/src/u2f_crate/util.rs
deleted file mode 100644
index cba58d4d7..000000000
--- a/plugins/authenticator/src/u2f_crate/util.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2021 Flavio Oliveira
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-use crate::u2f_crate::u2ferror::U2fError;
-use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
-use bytes::Bytes;
-use chrono::prelude::*;
-use chrono::Duration;
-use openssl::rand;
-
-/// The `Result` type used in this crate.
-type Result = ::std::result::Result;
-
-pub const U2F_V2: &str = "U2F_V2";
-
-// Generates a challenge from a secure, random source.
-pub fn generate_challenge(size: usize) -> Result> {
- let mut bytes: Vec = vec![0; size];
- rand::rand_bytes(&mut bytes).map_err(|_e| U2fError::RandomSecureBytesError)?;
- Ok(bytes)
-}
-
-pub fn expiration(timestamp: String) -> Duration {
- let now: DateTime = Utc::now();
-
- let ts = timestamp.parse::>();
-
- now.signed_duration_since(ts.unwrap())
-}
-
-// Decode initial bytes of buffer as ASN and return the length of the encoded structure.
-// http://en.wikipedia.org/wiki/X.690
-pub fn asn_length(mem: Bytes) -> Result {
- let buffer: &[u8] = &mem[..];
-
- if mem.len() < 2 || buffer[0] != 0x30 {
- // Type
- return Err(U2fError::Asm1DecoderError);
- }
-
- let len = buffer[1]; // Len
- if len & 0x80 == 0 {
- return Ok((len & 0x7f) as usize);
- }
-
- let numbem_of_bytes = len & 0x7f;
- if numbem_of_bytes == 0 {
- return Err(U2fError::Asm1DecoderError);
- }
-
- let mut length: usize = 0;
- for num in 0..numbem_of_bytes {
- length = length * 0x100 + (buffer[(2 + num) as usize] as usize);
- }
-
- length += numbem_of_bytes as usize;
-
- Ok(length + 2) // Add the 2 initial bytes: type and length.
-}
-
-pub fn get_encoded(data: &[u8]) -> String {
- let encoded: String = URL_SAFE_NO_PAD.encode(data);
-
- encoded.trim_end_matches('=').to_string()
-}
diff --git a/plugins/authenticator/tsconfig.json b/plugins/authenticator/tsconfig.json
deleted file mode 100644
index 5098169aa..000000000
--- a/plugins/authenticator/tsconfig.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "extends": "../../tsconfig.base.json",
- "include": ["guest-js/*.ts"]
-}
diff --git a/plugins/mirrors.txt b/plugins/mirrors.txt
index e981fdcb8..6c7f82835 100644
--- a/plugins/mirrors.txt
+++ b/plugins/mirrors.txt
@@ -1,4 +1,3 @@
-authenticator
autostart
fs-extra
fs-watch
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 37e3e84d0..115199b28 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -46,16 +46,6 @@ importers:
specifier: rc-v8
version: 8.0.0-alpha.62(eslint@9.9.1)(typescript@5.5.4)
- plugins/authenticator:
- dependencies:
- '@tauri-apps/api':
- specifier: 1.6.0
- version: 1.6.0
- devDependencies:
- tslib:
- specifier: 2.7.0
- version: 2.7.0
-
plugins/autostart:
dependencies:
'@tauri-apps/api':