Add support for the experimental wasi-crypto APIs (#2597)
* Add support for the experimental wasi-crypto APIs The sole purpose of the implementation is to allow bindings and application developers to test the proposed APIs. Rust and AssemblyScript bindings are also available as examples. Like `wasi-nn`, it is currently disabled by default, and requires the `wasi-crypto` feature flag to be compiled in. * Rename the wasi-crypto/spec submodule * Add a path dependency into the submodule for wasi-crypto * Tell the publish script to vendor wasi-crypto
This commit is contained in:
17
.github/workflows/main.yml
vendored
17
.github/workflows/main.yml
vendored
@@ -274,6 +274,7 @@ jobs:
|
||||
--exclude lightbeam \
|
||||
--exclude wasmtime-lightbeam \
|
||||
--exclude wasmtime-wasi-nn \
|
||||
--exclude wasmtime-wasi-crypto \
|
||||
--exclude peepmatic \
|
||||
--exclude peepmatic-automata \
|
||||
--exclude peepmatic-fuzzing \
|
||||
@@ -351,6 +352,21 @@ jobs:
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
# Build and test the wasi-crypto module.
|
||||
test_wasi_crypto:
|
||||
name: Test wasi-crypto module
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- run: rustup target add wasm32-wasi
|
||||
- name: Install Rust
|
||||
run: rustup update stable && rustup default stable
|
||||
- run: ./ci/run-wasi-crypto-example.sh
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
# Verify that cranelift's code generation is deterministic
|
||||
meta_determinist_check:
|
||||
name: Meta deterministic check
|
||||
@@ -459,6 +475,7 @@ jobs:
|
||||
--exclude lightbeam \
|
||||
--exclude wasmtime-lightbeam \
|
||||
--exclude wasmtime-wasi-nn \
|
||||
--exclude wasmtime-wasi-crypto \
|
||||
--exclude peepmatic \
|
||||
--exclude peepmatic-automata \
|
||||
--exclude peepmatic-fuzzing \
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -10,3 +10,6 @@
|
||||
[submodule "crates/wasi-nn/spec"]
|
||||
path = crates/wasi-nn/spec
|
||||
url = https://github.com/WebAssembly/wasi-nn
|
||||
[submodule "crates/wasi-crypto/spec"]
|
||||
path = crates/wasi-crypto/spec
|
||||
url = https://github.com/WebAssembly/wasi-crypto.git
|
||||
|
||||
869
Cargo.lock
generated
869
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,7 @@ wasmtime-jit = { path = "crates/jit", version = "0.22.0" }
|
||||
wasmtime-obj = { path = "crates/obj", version = "0.22.0" }
|
||||
wasmtime-wast = { path = "crates/wast", version = "0.22.0" }
|
||||
wasmtime-wasi = { path = "crates/wasi", version = "0.22.0" }
|
||||
wasmtime-wasi-crypto = { path = "crates/wasi-crypto", version = "0.22.0", optional = true }
|
||||
wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "0.22.0", optional = true }
|
||||
wasi-common = { path = "crates/wasi-common", version = "0.22.0" }
|
||||
structopt = { version = "0.3.5", features = ["color", "suggestions"] }
|
||||
@@ -82,6 +83,7 @@ default = ["jitdump", "wasmtime/wat", "wasmtime/parallel-compilation"]
|
||||
lightbeam = ["wasmtime/lightbeam"]
|
||||
jitdump = ["wasmtime/jitdump"]
|
||||
vtune = ["wasmtime/vtune"]
|
||||
wasi-crypto = ["wasmtime-wasi-crypto"]
|
||||
wasi-nn = ["wasmtime-wasi-nn"]
|
||||
|
||||
# Try the experimental, work-in-progress new x86_64 backend. This is not stable
|
||||
|
||||
@@ -14,6 +14,7 @@ cargo $CARGO_VERSION \
|
||||
--all \
|
||||
--exclude wasmtime-lightbeam \
|
||||
--exclude wasmtime-wasi-nn \
|
||||
--exclude wasmtime-wasi-crypto \
|
||||
--exclude peepmatic \
|
||||
--exclude peepmatic-automata \
|
||||
--exclude peepmatic-fuzzing \
|
||||
|
||||
10
ci/run-wasi-crypto-example.sh
Executable file
10
ci/run-wasi-crypto-example.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#! /bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
RUST_BINDINGS="crates/wasi-crypto/spec/implementations/bindings/rust"
|
||||
pushd "$RUST_BINDINGS"
|
||||
cargo build --release --target=wasm32-wasi
|
||||
popd
|
||||
|
||||
cargo run --features wasi-crypto -- run "$RUST_BINDINGS/target/wasm32-wasi/release/wasi-crypto-guest.wasm"
|
||||
@@ -83,7 +83,8 @@ fn main() -> anyhow::Result<()> {
|
||||
.arg("userenv.lib")
|
||||
.arg("ntdll.lib")
|
||||
.arg("shell32.lib")
|
||||
.arg("ole32.lib");
|
||||
.arg("ole32.lib")
|
||||
.arg("bcrypt.lib");
|
||||
if is_dir {
|
||||
"main.exe".to_string()
|
||||
} else {
|
||||
|
||||
22
crates/wasi-crypto/Cargo.toml
Normal file
22
crates/wasi-crypto/Cargo.toml
Normal file
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "wasmtime-wasi-crypto"
|
||||
version = "0.22.0"
|
||||
authors = ["The Wasmtime Project Developers"]
|
||||
description = "Wasmtime implementation of the wasi-crypto API"
|
||||
documentation = "https://docs.rs/wasmtime-wasi-crypto"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
categories = ["wasm", "cryptography"]
|
||||
keywords = ["webassembly", "wasm", "crypto"]
|
||||
repository = "https://github.com/bytecodealliance/wasmtime"
|
||||
readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
wasi-crypto = { path = "spec/implementations/hostcalls/rust", version = "0.1.4" }
|
||||
wasmtime = { path = "../wasmtime", version = "0.22.0", default-features = false }
|
||||
wasmtime-wiggle = { path = "../wiggle/wasmtime", version = "0.22.0" }
|
||||
wiggle = { path = "../wiggle", version = "0.22.0" }
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "experimental" }
|
||||
220
crates/wasi-crypto/LICENSE
Normal file
220
crates/wasi-crypto/LICENSE
Normal file
@@ -0,0 +1,220 @@
|
||||
|
||||
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
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
--- LLVM Exceptions to the Apache 2.0 License ----
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into an Object form of such source code, you
|
||||
may redistribute such embedded portions in such Object form without complying
|
||||
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
|
||||
|
||||
In addition, if you combine or link compiled forms of this Software with
|
||||
software that is licensed under the GPLv2 ("Combined Software") and if a
|
||||
court of competent jurisdiction determines that the patent provision (Section
|
||||
3), the indemnity provision (Section 9) or other Section of the License
|
||||
conflicts with the conditions of the GPLv2, you may retroactively and
|
||||
prospectively choose to deem waived or otherwise exclude such Section(s) of
|
||||
the License, but only in their entirety and only with respect to the Combined
|
||||
Software.
|
||||
|
||||
56
crates/wasi-crypto/README.md
Normal file
56
crates/wasi-crypto/README.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# wasmtime-wasi-crypto
|
||||
|
||||
This crate enables support for the [wasi-crypto] APIs in Wasmtime.
|
||||
|
||||
The sole purpose of the implementation is to allow bindings and
|
||||
application developers to test the proposed APIs. This implementation
|
||||
is not meant to be used in production. Like the specification, it is
|
||||
currently experimental and its functionality can quickly change.
|
||||
|
||||
Since the [wasi-crypto] API is expected to be an optional feature of
|
||||
WASI, this crate is currently separate from the [wasi-common] crate.
|
||||
|
||||
* [documentation]
|
||||
* [interfaces reference]
|
||||
* [interfaces reference (compact)]
|
||||
|
||||
[wasi-crypto]: https://github.com/WebAssembly/wasi-crypto
|
||||
[wasi-common]: ../../wasi-common
|
||||
[documentation]: ../spec/docs/wasi-crypto.md
|
||||
[interfaces reference]: ../spec/witx/wasi_ephemeral_crypto.md
|
||||
[interfaces reference (compact)]: ../spec/witx/wasi_ephemeral_crypto.txt
|
||||
|
||||
## Wasmtime integration
|
||||
|
||||
Use the Wasmtime APIs to instantiate a Wasm module and link the
|
||||
`wasi-crypto` modules as follows:
|
||||
|
||||
```rust
|
||||
use wasmtime_wasi_crypto::{
|
||||
WasiCryptoAsymmetricCommon, WasiCryptoCommon, WasiCryptoCtx, WasiCryptoSignatures,
|
||||
WasiCryptoSymmetric,
|
||||
};
|
||||
|
||||
let cx_crypto = WasiCryptoCtx::new();
|
||||
WasiCryptoCommon::new(linker.store(), cx_crypto.clone()).add_to_linker(linker)?;
|
||||
WasiCryptoAsymmetricCommon::new(linker.store(), cx_crypto.clone()).add_to_linker(linker)?;
|
||||
WasiCryptoSignatures::new(linker.store(), cx_crypto.clone()).add_to_linker(linker)?;
|
||||
WasiCryptoSymmetric::new(linker.store(), cx_crypto.clone()).add_to_linker(linker)?;
|
||||
|
||||
let wasi = wasmtime_wasi::old::snapshot_0::Wasi::new(linker.store(), mk_cx()?);
|
||||
wasi.add_to_linker(linker)?;
|
||||
```
|
||||
|
||||
## Building Wasmtime
|
||||
|
||||
Wasmtime must be compiled with the `wasi-crypto` feature flag
|
||||
(disabled by default) in order to include the crypto APIs.
|
||||
|
||||
## Examples
|
||||
|
||||
Example [rust bindings] and [assemblyscript bindings] are provided to
|
||||
demonstrate how these APIs can be used and exposed to applications in
|
||||
an idiomatic way.
|
||||
|
||||
[rust bindings]: ../spec/implementations/bindings/rust
|
||||
[assemblyscript bindings]: ../spec/implementations/bindings/assemblyscript
|
||||
1
crates/wasi-crypto/spec
Submodule
1
crates/wasi-crypto/spec
Submodule
Submodule crates/wasi-crypto/spec added at 6d7821dec3
31
crates/wasi-crypto/src/lib.rs
Normal file
31
crates/wasi-crypto/src/lib.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
mod wiggle_interfaces;
|
||||
|
||||
pub use wiggle_interfaces::WasiCryptoCtx;
|
||||
|
||||
wasmtime_wiggle::wasmtime_integration!({
|
||||
target: wiggle_interfaces::wasi_modules,
|
||||
witx: ["$CARGO_MANIFEST_DIR/spec/witx/wasi_ephemeral_crypto.witx"],
|
||||
ctx: WasiCryptoCtx,
|
||||
modules: {
|
||||
wasi_ephemeral_crypto_common =>
|
||||
{
|
||||
name: WasiCryptoCommon,
|
||||
docs: "wasi-crypto - Common module."
|
||||
},
|
||||
wasi_ephemeral_crypto_asymmetric_common =>
|
||||
{
|
||||
name: WasiCryptoAsymmetricCommon,
|
||||
docs: "wasi-crypto - Common module for asymmetric operations."
|
||||
},
|
||||
wasi_ephemeral_crypto_signatures =>
|
||||
{
|
||||
name: WasiCryptoSignatures,
|
||||
docs: "wasi-crypto - Signature module."
|
||||
},
|
||||
wasi_ephemeral_crypto_symmetric =>
|
||||
{
|
||||
name: WasiCryptoSymmetric,
|
||||
docs: "wasi-crypto - Symmetric cryptography module."
|
||||
}
|
||||
}
|
||||
});
|
||||
292
crates/wasi-crypto/src/wiggle_interfaces/asymmetric_common.rs
Normal file
292
crates/wasi-crypto/src/wiggle_interfaces/asymmetric_common.rs
Normal file
@@ -0,0 +1,292 @@
|
||||
use super::{guest_types, WasiCryptoCtx};
|
||||
|
||||
use std::convert::TryInto;
|
||||
use wasi_crypto::{ensure, CryptoError, KeyPairEncoding, PublicKeyEncoding, SecretKeyEncoding};
|
||||
|
||||
impl super::wasi_ephemeral_crypto_asymmetric_common::WasiEphemeralCryptoAsymmetricCommon
|
||||
for WasiCryptoCtx
|
||||
{
|
||||
// --- keypair_manager
|
||||
|
||||
fn keypair_generate_managed(
|
||||
&self,
|
||||
secrets_manager_handle: guest_types::SecretsManager,
|
||||
alg_type: guest_types::AlgorithmType,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
options_handle: &guest_types::OptOptions,
|
||||
) -> Result<guest_types::Keypair, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
let options_handle = match *options_handle {
|
||||
guest_types::OptOptions::Some(options_handle) => Some(options_handle),
|
||||
guest_types::OptOptions::None => None,
|
||||
};
|
||||
Ok(self
|
||||
.ctx
|
||||
.keypair_generate_managed(
|
||||
secrets_manager_handle.into(),
|
||||
alg_type.into(),
|
||||
alg_str,
|
||||
options_handle.map(Into::into),
|
||||
)?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn keypair_store_managed(
|
||||
&self,
|
||||
secrets_manager_handle: guest_types::SecretsManager,
|
||||
kp_handle: guest_types::Keypair,
|
||||
kp_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
kp_id_max_len: guest_types::Size,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let key_id_buf = &mut *kp_id_ptr.as_array(kp_id_max_len).as_slice_mut()?;
|
||||
Ok(self.ctx.keypair_store_managed(
|
||||
secrets_manager_handle.into(),
|
||||
kp_handle.into(),
|
||||
key_id_buf,
|
||||
)?)
|
||||
}
|
||||
|
||||
fn keypair_replace_managed(
|
||||
&self,
|
||||
secrets_manager_handle: guest_types::SecretsManager,
|
||||
kp_old_handle: guest_types::Keypair,
|
||||
kp_new_handle: guest_types::Keypair,
|
||||
) -> Result<guest_types::Version, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.keypair_replace_managed(
|
||||
secrets_manager_handle.into(),
|
||||
kp_old_handle.into(),
|
||||
kp_new_handle.into(),
|
||||
)?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn keypair_from_id(
|
||||
&self,
|
||||
secrets_manager_handle: guest_types::SecretsManager,
|
||||
kp_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
kp_id_len: guest_types::Size,
|
||||
kp_version: guest_types::Version,
|
||||
) -> Result<guest_types::Keypair, guest_types::CryptoErrno> {
|
||||
let kp_id = &*kp_id_ptr.as_array(kp_id_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.keypair_from_id(secrets_manager_handle.into(), kp_id, kp_version.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
// --- keypair
|
||||
|
||||
fn keypair_generate(
|
||||
&self,
|
||||
alg_type: guest_types::AlgorithmType,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
options_handle: &guest_types::OptOptions,
|
||||
) -> Result<guest_types::Keypair, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
let options_handle = match *options_handle {
|
||||
guest_types::OptOptions::Some(options_handle) => Some(options_handle),
|
||||
guest_types::OptOptions::None => None,
|
||||
};
|
||||
Ok(self
|
||||
.ctx
|
||||
.keypair_generate(alg_type.into(), alg_str, options_handle.map(Into::into))?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn keypair_import(
|
||||
&self,
|
||||
alg_type: guest_types::AlgorithmType,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
encoded_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
encoded_len: guest_types::Size,
|
||||
encoding: guest_types::KeypairEncoding,
|
||||
) -> Result<guest_types::Keypair, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
let encoded = &*encoded_ptr.as_array(encoded_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.keypair_import(alg_type.into(), alg_str, encoded, encoding.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn keypair_id(
|
||||
&self,
|
||||
kp_handle: guest_types::Keypair,
|
||||
kp_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
kp_id_max_len: guest_types::Size,
|
||||
) -> Result<(guest_types::Size, guest_types::Version), guest_types::CryptoErrno> {
|
||||
let kp_id_buf = &mut *kp_id_ptr.as_array(kp_id_max_len as _).as_slice_mut()?;
|
||||
let (kp_id, version) = self.ctx.keypair_id(kp_handle.into())?;
|
||||
ensure!(kp_id.len() <= kp_id_buf.len(), CryptoError::Overflow.into());
|
||||
kp_id_buf.copy_from_slice(&kp_id);
|
||||
Ok((kp_id.len().try_into()?, version.into()))
|
||||
}
|
||||
|
||||
fn keypair_export(
|
||||
&self,
|
||||
kp_handle: guest_types::Keypair,
|
||||
encoding: guest_types::KeypairEncoding,
|
||||
) -> Result<guest_types::ArrayOutput, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.keypair_export(kp_handle.into(), encoding.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn keypair_publickey(
|
||||
&self,
|
||||
kp_handle: guest_types::Keypair,
|
||||
) -> Result<guest_types::Publickey, guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.keypair_publickey(kp_handle.into())?.into())
|
||||
}
|
||||
|
||||
fn keypair_close(
|
||||
&self,
|
||||
kp_handle: guest_types::Keypair,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.keypair_close(kp_handle.into())?)
|
||||
}
|
||||
|
||||
// --- publickey
|
||||
|
||||
fn publickey_import(
|
||||
&self,
|
||||
alg_type: guest_types::AlgorithmType,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
encoded_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
encoded_len: guest_types::Size,
|
||||
encoding: guest_types::PublickeyEncoding,
|
||||
) -> Result<guest_types::Publickey, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
let encoded = &*encoded_ptr.as_array(encoded_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.publickey_import(alg_type.into(), alg_str, encoded, encoding.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn publickey_export(
|
||||
&self,
|
||||
pk_handle: guest_types::Publickey,
|
||||
encoding: guest_types::PublickeyEncoding,
|
||||
) -> Result<guest_types::ArrayOutput, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.publickey_export(pk_handle.into(), encoding.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn publickey_from_secretkey(
|
||||
&self,
|
||||
sk_handle: guest_types::Secretkey,
|
||||
) -> Result<guest_types::Publickey, guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.keypair_publickey(sk_handle.into())?.into())
|
||||
}
|
||||
|
||||
fn publickey_verify(
|
||||
&self,
|
||||
pk_handle: guest_types::Publickey,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.publickey_verify(pk_handle.into())?)
|
||||
}
|
||||
|
||||
fn publickey_close(
|
||||
&self,
|
||||
pk_handle: guest_types::Publickey,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.publickey_close(pk_handle.into())?)
|
||||
}
|
||||
|
||||
// --- secretkey
|
||||
|
||||
fn secretkey_import(
|
||||
&self,
|
||||
alg_type: guest_types::AlgorithmType,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
encoded_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
encoded_len: guest_types::Size,
|
||||
encoding: guest_types::SecretkeyEncoding,
|
||||
) -> Result<guest_types::Secretkey, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
let encoded = &*encoded_ptr.as_array(encoded_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.secretkey_import(alg_type.into(), alg_str, encoded, encoding.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn secretkey_export(
|
||||
&self,
|
||||
sk_handle: guest_types::Secretkey,
|
||||
encoding: guest_types::SecretkeyEncoding,
|
||||
) -> Result<guest_types::ArrayOutput, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.secretkey_export(sk_handle.into(), encoding.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn secretkey_close(
|
||||
&self,
|
||||
sk_handle: guest_types::Secretkey,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.secretkey_close(sk_handle.into())?)
|
||||
}
|
||||
|
||||
fn keypair_from_pk_and_sk(
|
||||
&self,
|
||||
pk_handle: guest_types::Publickey,
|
||||
sk_handle: guest_types::Secretkey,
|
||||
) -> Result<guest_types::Keypair, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.keypair_from_pk_and_sk(pk_handle.into(), sk_handle.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn keypair_secretkey(
|
||||
&self,
|
||||
kp_handle: guest_types::Keypair,
|
||||
) -> Result<guest_types::Secretkey, guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.keypair_secretkey(kp_handle.into())?.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<guest_types::KeypairEncoding> for KeyPairEncoding {
|
||||
fn from(encoding: guest_types::KeypairEncoding) -> Self {
|
||||
match encoding {
|
||||
guest_types::KeypairEncoding::Raw => KeyPairEncoding::Raw,
|
||||
guest_types::KeypairEncoding::Pkcs8 => KeyPairEncoding::Pkcs8,
|
||||
guest_types::KeypairEncoding::Pem => KeyPairEncoding::Pem,
|
||||
guest_types::KeypairEncoding::Local => KeyPairEncoding::Local,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<guest_types::PublickeyEncoding> for PublicKeyEncoding {
|
||||
fn from(encoding: guest_types::PublickeyEncoding) -> Self {
|
||||
match encoding {
|
||||
guest_types::PublickeyEncoding::Raw => PublicKeyEncoding::Raw,
|
||||
guest_types::PublickeyEncoding::Pkcs8 => PublicKeyEncoding::Pkcs8,
|
||||
guest_types::PublickeyEncoding::Pem => PublicKeyEncoding::Pem,
|
||||
guest_types::PublickeyEncoding::Sec => PublicKeyEncoding::Sec,
|
||||
guest_types::PublickeyEncoding::CompressedSec => PublicKeyEncoding::CompressedSec,
|
||||
guest_types::PublickeyEncoding::Local => PublicKeyEncoding::Local,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<guest_types::SecretkeyEncoding> for SecretKeyEncoding {
|
||||
fn from(encoding: guest_types::SecretkeyEncoding) -> Self {
|
||||
match encoding {
|
||||
guest_types::SecretkeyEncoding::Raw => SecretKeyEncoding::Raw,
|
||||
guest_types::SecretkeyEncoding::Pkcs8 => SecretKeyEncoding::Pkcs8,
|
||||
guest_types::SecretkeyEncoding::Pem => SecretKeyEncoding::Pem,
|
||||
guest_types::SecretkeyEncoding::Sec => SecretKeyEncoding::Sec,
|
||||
guest_types::SecretkeyEncoding::CompressedSec => SecretKeyEncoding::CompressedSec,
|
||||
guest_types::SecretkeyEncoding::Local => SecretKeyEncoding::Local,
|
||||
}
|
||||
}
|
||||
}
|
||||
150
crates/wasi-crypto/src/wiggle_interfaces/common.rs
Normal file
150
crates/wasi-crypto/src/wiggle_interfaces/common.rs
Normal file
@@ -0,0 +1,150 @@
|
||||
use super::{guest_types, WasiCryptoCtx};
|
||||
|
||||
use std::convert::TryInto;
|
||||
use wasi_crypto::{AlgorithmType, Version};
|
||||
|
||||
impl super::wasi_ephemeral_crypto_common::WasiEphemeralCryptoCommon for WasiCryptoCtx {
|
||||
// --- options
|
||||
|
||||
fn options_open(
|
||||
&self,
|
||||
options_type: guest_types::AlgorithmType,
|
||||
) -> Result<guest_types::Options, guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.options_open(options_type.into())?.into())
|
||||
}
|
||||
|
||||
fn options_close(
|
||||
&self,
|
||||
options_handle: guest_types::Options,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.options_close(options_handle.into())?)
|
||||
}
|
||||
|
||||
fn options_set(
|
||||
&self,
|
||||
options_handle: guest_types::Options,
|
||||
name_str: &wiggle::GuestPtr<'_, str>,
|
||||
value_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
value_len: guest_types::Size,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let name_str: &str = &*name_str.as_str()?;
|
||||
let value: &[u8] = { &*value_ptr.as_array(value_len).as_slice()? };
|
||||
Ok(self
|
||||
.ctx
|
||||
.options_set(options_handle.into(), name_str, value)?)
|
||||
}
|
||||
|
||||
fn options_set_guest_buffer(
|
||||
&self,
|
||||
options_handle: guest_types::Options,
|
||||
name_str: &wiggle::GuestPtr<'_, str>,
|
||||
buffer_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
buffer_len: guest_types::Size,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let name_str: &str = &*name_str.as_str()?;
|
||||
let buffer: &'static mut [u8] =
|
||||
unsafe { std::mem::transmute(&mut *buffer_ptr.as_array(buffer_len).as_slice_mut()?) };
|
||||
Ok(self
|
||||
.ctx
|
||||
.options_set_guest_buffer(options_handle.into(), name_str, buffer)?)
|
||||
}
|
||||
|
||||
fn options_set_u64(
|
||||
&self,
|
||||
options_handle: guest_types::Options,
|
||||
name_str: &wiggle::GuestPtr<'_, str>,
|
||||
value: u64,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let name_str: &str = &*name_str.as_str()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.options_set_u64(options_handle.into(), name_str, value)?)
|
||||
}
|
||||
|
||||
// --- array
|
||||
|
||||
fn array_output_len(
|
||||
&self,
|
||||
array_output_handle: guest_types::ArrayOutput,
|
||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.array_output_len(array_output_handle.into())?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
fn array_output_pull(
|
||||
&self,
|
||||
array_output_handle: guest_types::ArrayOutput,
|
||||
buf_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
buf_len: guest_types::Size,
|
||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||
let buf: &mut [u8] = { &mut *buf_ptr.as_array(buf_len).as_slice_mut()? };
|
||||
Ok(self
|
||||
.ctx
|
||||
.array_output_pull(array_output_handle.into(), buf)?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
// --- secrets_manager
|
||||
|
||||
fn secrets_manager_open(
|
||||
&self,
|
||||
options_handle: &guest_types::OptOptions,
|
||||
) -> Result<guest_types::SecretsManager, guest_types::CryptoErrno> {
|
||||
let options_handle = match *options_handle {
|
||||
guest_types::OptOptions::Some(options_handle) => Some(options_handle),
|
||||
guest_types::OptOptions::None => None,
|
||||
};
|
||||
Ok(self
|
||||
.ctx
|
||||
.secrets_manager_open(options_handle.map(Into::into))?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn secrets_manager_close(
|
||||
&self,
|
||||
secrets_manager_handle: guest_types::SecretsManager,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.secrets_manager_close(secrets_manager_handle.into())?)
|
||||
}
|
||||
|
||||
fn secrets_manager_invalidate(
|
||||
&self,
|
||||
secrets_manager_handle: guest_types::SecretsManager,
|
||||
key_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
key_id_len: guest_types::Size,
|
||||
key_version: guest_types::Version,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let key_id: &[u8] = { &*key_id_ptr.as_array(key_id_len).as_slice()? };
|
||||
Ok(self.ctx.secrets_manager_invalidate(
|
||||
secrets_manager_handle.into(),
|
||||
key_id,
|
||||
key_version.into(),
|
||||
)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<guest_types::AlgorithmType> for AlgorithmType {
|
||||
fn from(options_type: guest_types::AlgorithmType) -> Self {
|
||||
match options_type {
|
||||
guest_types::AlgorithmType::Signatures => AlgorithmType::Signatures,
|
||||
guest_types::AlgorithmType::Symmetric => AlgorithmType::Symmetric,
|
||||
guest_types::AlgorithmType::KeyExchange => AlgorithmType::KeyExchange,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<guest_types::Version> for Version {
|
||||
fn from(version: guest_types::Version) -> Self {
|
||||
Version(version.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Version> for guest_types::Version {
|
||||
fn from(version: Version) -> Self {
|
||||
version.into()
|
||||
}
|
||||
}
|
||||
67
crates/wasi-crypto/src/wiggle_interfaces/error.rs
Normal file
67
crates/wasi-crypto/src/wiggle_interfaces/error.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
use super::{guest_types, WasiCryptoCtx};
|
||||
|
||||
use std::num::TryFromIntError;
|
||||
use wasi_crypto::CryptoError;
|
||||
|
||||
impl From<CryptoError> for guest_types::CryptoErrno {
|
||||
fn from(e: CryptoError) -> Self {
|
||||
match e {
|
||||
CryptoError::Success => guest_types::CryptoErrno::Success,
|
||||
CryptoError::GuestError(_wiggle_error) => guest_types::CryptoErrno::GuestError,
|
||||
CryptoError::NotImplemented => guest_types::CryptoErrno::NotImplemented,
|
||||
CryptoError::UnsupportedFeature => guest_types::CryptoErrno::UnsupportedFeature,
|
||||
CryptoError::ProhibitedOperation => guest_types::CryptoErrno::ProhibitedOperation,
|
||||
CryptoError::UnsupportedEncoding => guest_types::CryptoErrno::UnsupportedEncoding,
|
||||
CryptoError::UnsupportedAlgorithm => guest_types::CryptoErrno::UnsupportedAlgorithm,
|
||||
CryptoError::UnsupportedOption => guest_types::CryptoErrno::UnsupportedOption,
|
||||
CryptoError::InvalidKey => guest_types::CryptoErrno::InvalidKey,
|
||||
CryptoError::InvalidLength => guest_types::CryptoErrno::InvalidLength,
|
||||
CryptoError::VerificationFailed => guest_types::CryptoErrno::VerificationFailed,
|
||||
CryptoError::RNGError => guest_types::CryptoErrno::RngError,
|
||||
CryptoError::AlgorithmFailure => guest_types::CryptoErrno::AlgorithmFailure,
|
||||
CryptoError::InvalidSignature => guest_types::CryptoErrno::InvalidSignature,
|
||||
CryptoError::Closed => guest_types::CryptoErrno::Closed,
|
||||
CryptoError::InvalidHandle => guest_types::CryptoErrno::InvalidHandle,
|
||||
CryptoError::Overflow => guest_types::CryptoErrno::Overflow,
|
||||
CryptoError::InternalError => guest_types::CryptoErrno::InternalError,
|
||||
CryptoError::TooManyHandles => guest_types::CryptoErrno::TooManyHandles,
|
||||
CryptoError::KeyNotSupported => guest_types::CryptoErrno::KeyNotSupported,
|
||||
CryptoError::KeyRequired => guest_types::CryptoErrno::KeyRequired,
|
||||
CryptoError::InvalidTag => guest_types::CryptoErrno::InvalidTag,
|
||||
CryptoError::InvalidOperation => guest_types::CryptoErrno::InvalidOperation,
|
||||
CryptoError::NonceRequired => guest_types::CryptoErrno::NonceRequired,
|
||||
CryptoError::InvalidNonce => guest_types::CryptoErrno::InvalidNonce,
|
||||
CryptoError::OptionNotSet => guest_types::CryptoErrno::OptionNotSet,
|
||||
CryptoError::NotFound => guest_types::CryptoErrno::NotFound,
|
||||
CryptoError::ParametersMissing => guest_types::CryptoErrno::ParametersMissing,
|
||||
CryptoError::IncompatibleKeys => guest_types::CryptoErrno::IncompatibleKeys,
|
||||
CryptoError::Expired => guest_types::CryptoErrno::Expired,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TryFromIntError> for guest_types::CryptoErrno {
|
||||
fn from(_: TryFromIntError) -> Self {
|
||||
CryptoError::Overflow.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> wiggle::GuestErrorType for guest_types::CryptoErrno {
|
||||
fn success() -> Self {
|
||||
guest_types::CryptoErrno::Success
|
||||
}
|
||||
}
|
||||
|
||||
impl guest_types::GuestErrorConversion for WasiCryptoCtx {
|
||||
fn into_crypto_errno(&self, e: wiggle::GuestError) -> guest_types::CryptoErrno {
|
||||
eprintln!("GuestError (witx) {:?}", e);
|
||||
guest_types::CryptoErrno::GuestError
|
||||
}
|
||||
}
|
||||
|
||||
impl From<wiggle::GuestError> for guest_types::CryptoErrno {
|
||||
fn from(e: wiggle::GuestError) -> Self {
|
||||
eprintln!("GuestError (impl) {:?}", e);
|
||||
guest_types::CryptoErrno::GuestError
|
||||
}
|
||||
}
|
||||
40
crates/wasi-crypto/src/wiggle_interfaces/key_exchange.rs
Normal file
40
crates/wasi-crypto/src/wiggle_interfaces/key_exchange.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
use super::{guest_types, WasiCryptoCtx};
|
||||
|
||||
impl super::wasi_ephemeral_crypto_kx::WasiEphemeralCryptoKx for WasiCryptoCtx {
|
||||
// --- key exchange
|
||||
|
||||
fn kx_dh(
|
||||
&self,
|
||||
pk_handle: guest_types::Publickey,
|
||||
sk_handle: guest_types::Secretkey,
|
||||
) -> Result<guest_types::ArrayOutput, guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.kx_dh(pk_handle.into(), sk_handle.into())?.into())
|
||||
}
|
||||
|
||||
// --- Key encapsulation
|
||||
|
||||
fn kx_encapsulate(
|
||||
&self,
|
||||
pk_handle: guest_types::Publickey,
|
||||
) -> Result<(guest_types::ArrayOutput, guest_types::ArrayOutput), guest_types::CryptoErrno>
|
||||
{
|
||||
let (secret_handle, encapsulated_secret_handle) =
|
||||
self.ctx.kx_encapsulate(pk_handle.into())?;
|
||||
Ok((secret_handle.into(), encapsulated_secret_handle.into()))
|
||||
}
|
||||
|
||||
fn kx_decapsulate(
|
||||
&self,
|
||||
sk_handle: guest_types::Secretkey,
|
||||
encapsulated_secret_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
encapsulated_secret_len: guest_types::Size,
|
||||
) -> Result<guest_types::ArrayOutput, guest_types::CryptoErrno> {
|
||||
let encapsulated_secret = &*encapsulated_secret_ptr
|
||||
.as_array(encapsulated_secret_len)
|
||||
.as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.kx_decapsulate(sk_handle.into(), encapsulated_secret)?
|
||||
.into())
|
||||
}
|
||||
}
|
||||
38
crates/wasi-crypto/src/wiggle_interfaces/mod.rs
Normal file
38
crates/wasi-crypto/src/wiggle_interfaces/mod.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use wasi_crypto::CryptoCtx;
|
||||
|
||||
wiggle::from_witx!({
|
||||
witx: ["$CARGO_MANIFEST_DIR/spec/witx/wasi_ephemeral_crypto.witx"],
|
||||
ctx: WasiCryptoCtx
|
||||
});
|
||||
|
||||
pub mod wasi_modules {
|
||||
pub use super::{
|
||||
wasi_ephemeral_crypto_asymmetric_common, wasi_ephemeral_crypto_common,
|
||||
wasi_ephemeral_crypto_kx, wasi_ephemeral_crypto_signatures,
|
||||
wasi_ephemeral_crypto_symmetric,
|
||||
};
|
||||
}
|
||||
|
||||
pub use types as guest_types;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WasiCryptoCtx {
|
||||
ctx: Rc<CryptoCtx>,
|
||||
}
|
||||
|
||||
impl WasiCryptoCtx {
|
||||
pub fn new() -> Self {
|
||||
WasiCryptoCtx {
|
||||
ctx: Rc::new(CryptoCtx::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod asymmetric_common;
|
||||
mod common;
|
||||
mod error;
|
||||
mod key_exchange;
|
||||
mod signatures;
|
||||
mod symmetric;
|
||||
129
crates/wasi-crypto/src/wiggle_interfaces/signatures.rs
Normal file
129
crates/wasi-crypto/src/wiggle_interfaces/signatures.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
use super::{guest_types, WasiCryptoCtx};
|
||||
|
||||
use wasi_crypto::SignatureEncoding;
|
||||
|
||||
impl super::wasi_ephemeral_crypto_signatures::WasiEphemeralCryptoSignatures for WasiCryptoCtx {
|
||||
// --- signature
|
||||
|
||||
fn signature_export(
|
||||
&self,
|
||||
signature_handle: guest_types::Signature,
|
||||
encoding: guest_types::SignatureEncoding,
|
||||
) -> Result<guest_types::ArrayOutput, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.signature_export(signature_handle.into(), encoding.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn signature_import(
|
||||
&self,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
encoded_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
encoded_len: guest_types::Size,
|
||||
encoding: guest_types::SignatureEncoding,
|
||||
) -> Result<guest_types::Signature, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
let encoded = &*encoded_ptr.as_array(encoded_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.signature_import(alg_str, encoded, encoding.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn signature_state_open(
|
||||
&self,
|
||||
kp_handle: guest_types::Keypair,
|
||||
) -> Result<guest_types::SignatureState, guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.signature_state_open(kp_handle.into())?.into())
|
||||
}
|
||||
|
||||
fn signature_state_update(
|
||||
&self,
|
||||
state_handle: guest_types::SignatureState,
|
||||
input_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
input_len: guest_types::Size,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let input = &*input_ptr.as_array(input_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.signature_state_update(state_handle.into(), input)?)
|
||||
}
|
||||
|
||||
fn signature_state_sign(
|
||||
&self,
|
||||
signature_state_handle: guest_types::SignatureState,
|
||||
) -> Result<guest_types::ArrayOutput, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.signature_state_sign(signature_state_handle.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn signature_state_close(
|
||||
&self,
|
||||
signature_state_handle: guest_types::SignatureState,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.signature_state_close(signature_state_handle.into())?)
|
||||
}
|
||||
|
||||
fn signature_verification_state_open(
|
||||
&self,
|
||||
pk_handle: guest_types::Publickey,
|
||||
) -> Result<guest_types::SignatureVerificationState, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.signature_verification_state_open(pk_handle.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn signature_verification_state_update(
|
||||
&self,
|
||||
verification_state_handle: guest_types::SignatureVerificationState,
|
||||
input_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
input_len: guest_types::Size,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let input: &[u8] = &*input_ptr.as_array(input_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.signature_verification_state_update(verification_state_handle.into(), input)?)
|
||||
}
|
||||
|
||||
fn signature_verification_state_verify(
|
||||
&self,
|
||||
verification_state_handle: guest_types::SignatureVerificationState,
|
||||
signature_handle: guest_types::Signature,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.signature_verification_state_verify(
|
||||
verification_state_handle.into(),
|
||||
signature_handle.into(),
|
||||
)?)
|
||||
}
|
||||
|
||||
fn signature_verification_state_close(
|
||||
&self,
|
||||
verification_state_handle: guest_types::SignatureVerificationState,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.signature_verification_state_close(verification_state_handle.into())?)
|
||||
}
|
||||
|
||||
fn signature_close(
|
||||
&self,
|
||||
signature_handle: guest_types::Signature,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.signature_close(signature_handle.into())?)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<guest_types::SignatureEncoding> for SignatureEncoding {
|
||||
fn from(encoding: guest_types::SignatureEncoding) -> Self {
|
||||
match encoding {
|
||||
guest_types::SignatureEncoding::Raw => SignatureEncoding::Raw,
|
||||
guest_types::SignatureEncoding::Der => SignatureEncoding::Der,
|
||||
}
|
||||
}
|
||||
}
|
||||
384
crates/wasi-crypto/src/wiggle_interfaces/symmetric.rs
Normal file
384
crates/wasi-crypto/src/wiggle_interfaces/symmetric.rs
Normal file
@@ -0,0 +1,384 @@
|
||||
use super::{guest_types, WasiCryptoCtx};
|
||||
|
||||
use std::convert::TryInto;
|
||||
use wasi_crypto::{ensure, CryptoError};
|
||||
|
||||
impl super::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for WasiCryptoCtx {
|
||||
// --- secrets_manager
|
||||
|
||||
fn symmetric_key_generate_managed(
|
||||
&self,
|
||||
secrets_manager_handle: guest_types::SecretsManager,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
options_handle: &guest_types::OptOptions,
|
||||
) -> Result<guest_types::SymmetricKey, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
let options_handle = match *options_handle {
|
||||
guest_types::OptOptions::Some(options_handle) => Some(options_handle),
|
||||
guest_types::OptOptions::None => None,
|
||||
};
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_key_generate_managed(
|
||||
secrets_manager_handle.into(),
|
||||
alg_str,
|
||||
options_handle.map(Into::into),
|
||||
)?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn symmetric_key_store_managed(
|
||||
&self,
|
||||
secrets_manager_handle: guest_types::SecretsManager,
|
||||
symmetric_key_handle: guest_types::SymmetricKey,
|
||||
symmetric_key_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
symmetric_key_id_max_len: guest_types::Size,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let key_id_buf = &mut *symmetric_key_id_ptr
|
||||
.as_array(symmetric_key_id_max_len)
|
||||
.as_slice_mut()?;
|
||||
Ok(self.ctx.symmetric_key_store_managed(
|
||||
secrets_manager_handle.into(),
|
||||
symmetric_key_handle.into(),
|
||||
key_id_buf,
|
||||
)?)
|
||||
}
|
||||
|
||||
fn symmetric_key_replace_managed(
|
||||
&self,
|
||||
secrets_manager_handle: guest_types::SecretsManager,
|
||||
symmetric_key_old_handle: guest_types::SymmetricKey,
|
||||
symmetric_key_new_handle: guest_types::SymmetricKey,
|
||||
) -> Result<guest_types::Version, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_key_replace_managed(
|
||||
secrets_manager_handle.into(),
|
||||
symmetric_key_old_handle.into(),
|
||||
symmetric_key_new_handle.into(),
|
||||
)?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn symmetric_key_from_id(
|
||||
&self,
|
||||
secrets_manager_handle: guest_types::SecretsManager,
|
||||
symmetric_key_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
symmetric_key_id_len: guest_types::Size,
|
||||
symmetric_key_version: guest_types::Version,
|
||||
) -> Result<guest_types::SymmetricKey, guest_types::CryptoErrno> {
|
||||
let symmetric_key_id = &*symmetric_key_id_ptr
|
||||
.as_array(symmetric_key_id_len)
|
||||
.as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_key_from_id(
|
||||
secrets_manager_handle.into(),
|
||||
symmetric_key_id,
|
||||
symmetric_key_version.into(),
|
||||
)?
|
||||
.into())
|
||||
}
|
||||
|
||||
// --- key
|
||||
|
||||
fn symmetric_key_generate(
|
||||
&self,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
options_handle: &guest_types::OptOptions,
|
||||
) -> Result<guest_types::SymmetricKey, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
let options_handle = match *options_handle {
|
||||
guest_types::OptOptions::Some(options_handle) => Some(options_handle),
|
||||
guest_types::OptOptions::None => None,
|
||||
};
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_key_generate(alg_str, options_handle.map(Into::into))?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn symmetric_key_import(
|
||||
&self,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
raw_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
raw_len: guest_types::Size,
|
||||
) -> Result<guest_types::SymmetricKey, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
let raw = &*raw_ptr.as_array(raw_len).as_slice()?;
|
||||
Ok(self.ctx.symmetric_key_import(alg_str, raw)?.into())
|
||||
}
|
||||
|
||||
fn symmetric_key_export(
|
||||
&self,
|
||||
symmetric_key_handle: guest_types::SymmetricKey,
|
||||
) -> Result<guest_types::ArrayOutput, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_key_export(symmetric_key_handle.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn symmetric_key_id(
|
||||
&self,
|
||||
symmetric_key_handle: guest_types::SymmetricKey,
|
||||
symmetric_key_id_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
symmetric_key_id_max_len: guest_types::Size,
|
||||
) -> Result<(guest_types::Size, guest_types::Version), guest_types::CryptoErrno> {
|
||||
let key_id_buf = &mut *symmetric_key_id_ptr
|
||||
.as_array(symmetric_key_id_max_len)
|
||||
.as_slice_mut()?;
|
||||
let (key_id, version) = self.ctx.symmetric_key_id(symmetric_key_handle.into())?;
|
||||
ensure!(
|
||||
key_id.len() <= key_id_buf.len(),
|
||||
CryptoError::Overflow.into()
|
||||
);
|
||||
key_id_buf.copy_from_slice(&key_id);
|
||||
Ok((key_id.len().try_into()?, version.into()))
|
||||
}
|
||||
|
||||
fn symmetric_key_close(
|
||||
&self,
|
||||
key_handle: guest_types::SymmetricKey,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.symmetric_key_close(key_handle.into())?)
|
||||
}
|
||||
|
||||
// --- state
|
||||
|
||||
fn symmetric_state_open(
|
||||
&self,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
key_handle: &guest_types::OptSymmetricKey,
|
||||
options_handle: &guest_types::OptOptions,
|
||||
) -> Result<guest_types::SymmetricState, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
let key_handle = match *key_handle {
|
||||
guest_types::OptSymmetricKey::Some(key_handle) => Some(key_handle),
|
||||
guest_types::OptSymmetricKey::None => None,
|
||||
};
|
||||
let options_handle = match *options_handle {
|
||||
guest_types::OptOptions::Some(options_handle) => Some(options_handle),
|
||||
guest_types::OptOptions::None => None,
|
||||
};
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_open(
|
||||
alg_str,
|
||||
key_handle.map(Into::into),
|
||||
options_handle.map(Into::into),
|
||||
)?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn symmetric_state_options_get(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
name_str: &wiggle::GuestPtr<'_, str>,
|
||||
value_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
value_max_len: guest_types::Size,
|
||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||
let name_str: &str = &*name_str.as_str()?;
|
||||
let value = &mut *value_ptr.as_array(value_max_len).as_slice_mut()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.options_get(symmetric_state_handle.into(), name_str, value)?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
fn symmetric_state_options_get_u64(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
name_str: &wiggle::GuestPtr<'_, str>,
|
||||
) -> Result<u64, guest_types::CryptoErrno> {
|
||||
let name_str: &str = &*name_str.as_str()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.options_get_u64(symmetric_state_handle.into(), name_str)?)
|
||||
}
|
||||
|
||||
fn symmetric_state_close(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_close(symmetric_state_handle.into())?)
|
||||
}
|
||||
|
||||
fn symmetric_state_absorb(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
data_len: guest_types::Size,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let data = &*data_ptr.as_array(data_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_absorb(symmetric_state_handle.into(), data)?)
|
||||
}
|
||||
|
||||
fn symmetric_state_squeeze(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
out_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
out_len: guest_types::Size,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let out = &mut *out_ptr.as_array(out_len).as_slice_mut()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_squeeze(symmetric_state_handle.into(), out)?)
|
||||
}
|
||||
|
||||
fn symmetric_state_squeeze_tag(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
) -> Result<guest_types::SymmetricTag, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_squeeze_tag(symmetric_state_handle.into())?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn symmetric_state_squeeze_key(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
alg_str: &wiggle::GuestPtr<'_, str>,
|
||||
) -> Result<guest_types::SymmetricKey, guest_types::CryptoErrno> {
|
||||
let alg_str = &*alg_str.as_str()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_squeeze_key(symmetric_state_handle.into(), alg_str)?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn symmetric_state_max_tag_len(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_max_tag_len(symmetric_state_handle.into())?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
fn symmetric_state_encrypt(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
out_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
out_len: guest_types::Size,
|
||||
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
data_len: guest_types::Size,
|
||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||
let out = &mut *out_ptr.as_array(out_len).as_slice_mut()?;
|
||||
let data = &*data_ptr.as_array(data_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_encrypt(symmetric_state_handle.into(), out, data)?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
fn symmetric_state_encrypt_detached(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
out_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
out_len: guest_types::Size,
|
||||
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
data_len: guest_types::Size,
|
||||
) -> Result<guest_types::SymmetricTag, guest_types::CryptoErrno> {
|
||||
let out = &mut *out_ptr.as_array(out_len).as_slice_mut()?;
|
||||
let data = &*data_ptr.as_array(data_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_encrypt_detached(symmetric_state_handle.into(), out, data)?
|
||||
.into())
|
||||
}
|
||||
|
||||
fn symmetric_state_decrypt(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
out_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
out_len: guest_types::Size,
|
||||
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
data_len: guest_types::Size,
|
||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||
let out = &mut *out_ptr.as_array(out_len).as_slice_mut()?;
|
||||
let data = &*data_ptr.as_array(data_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_decrypt(symmetric_state_handle.into(), out, data)?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
fn symmetric_state_decrypt_detached(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
out_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
out_len: guest_types::Size,
|
||||
data_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
data_len: guest_types::Size,
|
||||
raw_tag_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
raw_tag_len: guest_types::Size,
|
||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||
let out = &mut *out_ptr.as_array(out_len).as_slice_mut()?;
|
||||
let data = &*data_ptr.as_array(data_len).as_slice()?;
|
||||
let raw_tag: &[u8] = &*raw_tag_ptr.as_array(raw_tag_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_decrypt_detached(symmetric_state_handle.into(), out, data, raw_tag)?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
fn symmetric_state_ratchet(
|
||||
&self,
|
||||
symmetric_state_handle: guest_types::SymmetricState,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_state_ratchet(symmetric_state_handle.into())?)
|
||||
}
|
||||
|
||||
// --- tag
|
||||
|
||||
fn symmetric_tag_len(
|
||||
&self,
|
||||
symmetric_tag_handle: guest_types::SymmetricTag,
|
||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_tag_len(symmetric_tag_handle.into())?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
fn symmetric_tag_pull(
|
||||
&self,
|
||||
symmetric_tag_handle: guest_types::SymmetricTag,
|
||||
buf_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
buf_len: guest_types::Size,
|
||||
) -> Result<guest_types::Size, guest_types::CryptoErrno> {
|
||||
let buf = &mut *buf_ptr.as_array(buf_len).as_slice_mut()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_tag_pull(symmetric_tag_handle.into(), buf)?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
fn symmetric_tag_verify(
|
||||
&self,
|
||||
symmetric_tag_handle: guest_types::SymmetricTag,
|
||||
expected_raw_ptr: &wiggle::GuestPtr<'_, u8>,
|
||||
expected_raw_len: guest_types::Size,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
let expected_raw = &*expected_raw_ptr.as_array(expected_raw_len).as_slice()?;
|
||||
Ok(self
|
||||
.ctx
|
||||
.symmetric_tag_verify(symmetric_tag_handle.into(), expected_raw)?)
|
||||
}
|
||||
|
||||
fn symmetric_tag_close(
|
||||
&self,
|
||||
symmetric_tag_handle: guest_types::SymmetricTag,
|
||||
) -> Result<(), guest_types::CryptoErrno> {
|
||||
Ok(self.ctx.symmetric_tag_close(symmetric_tag_handle.into())?)
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@ const CRATES_TO_PUBLISH: &[&str] = &[
|
||||
"wasmtime-wiggle",
|
||||
"wasmtime-wasi",
|
||||
"wasmtime-wasi-nn",
|
||||
"wasmtime-wasi-crypto",
|
||||
"wasmtime-rust-macro",
|
||||
"wasmtime-rust",
|
||||
"wasmtime-wast",
|
||||
@@ -176,7 +177,7 @@ fn read_crate(manifest: &Path) -> Crate {
|
||||
} else {
|
||||
version.clone()
|
||||
};
|
||||
if name == "witx" {
|
||||
if ["witx", "wasi-crypto"].contains(&&name[..]) {
|
||||
publish = false;
|
||||
}
|
||||
Crate {
|
||||
@@ -299,6 +300,13 @@ fn verify(crates: &[Crate]) {
|
||||
.unwrap();
|
||||
verify_and_vendor(&witx);
|
||||
|
||||
// Vendor wasi-crypto which is also a path dependency
|
||||
let wasi_crypto = crates
|
||||
.iter()
|
||||
.find(|c| c.name == "wasi-crypto")
|
||||
.unwrap();
|
||||
verify_and_vendor(&wasi_crypto);
|
||||
|
||||
for krate in crates {
|
||||
if !krate.publish {
|
||||
continue;
|
||||
|
||||
@@ -18,6 +18,12 @@ use wasmtime_wasi::Wasi;
|
||||
#[cfg(feature = "wasi-nn")]
|
||||
use wasmtime_wasi_nn::{WasiNn, WasiNnCtx};
|
||||
|
||||
#[cfg(feature = "wasi-crypto")]
|
||||
use wasmtime_wasi_crypto::{
|
||||
WasiCryptoAsymmetricCommon, WasiCryptoCommon, WasiCryptoCtx, WasiCryptoSignatures,
|
||||
WasiCryptoSymmetric,
|
||||
};
|
||||
|
||||
fn parse_module(s: &OsStr) -> Result<PathBuf, OsString> {
|
||||
// Do not accept wasmtime subcommand names as the module name
|
||||
match s.to_str() {
|
||||
@@ -364,6 +370,15 @@ fn populate_with_wasi(
|
||||
wasi_nn.add_to_linker(linker)?;
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasi-crypto")]
|
||||
{
|
||||
let cx_crypto = WasiCryptoCtx::new();
|
||||
WasiCryptoCommon::new(linker.store(), cx_crypto.clone()).add_to_linker(linker)?;
|
||||
WasiCryptoAsymmetricCommon::new(linker.store(), cx_crypto.clone()).add_to_linker(linker)?;
|
||||
WasiCryptoSignatures::new(linker.store(), cx_crypto.clone()).add_to_linker(linker)?;
|
||||
WasiCryptoSymmetric::new(linker.store(), cx_crypto.clone()).add_to_linker(linker)?;
|
||||
}
|
||||
|
||||
let wasi = wasmtime_wasi::old::snapshot_0::Wasi::new(linker.store(), mk_cx()?);
|
||||
wasi.add_to_linker(linker)?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user