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:
Frank Denis
2021-01-25 16:32:58 +01:00
committed by GitHub
parent 95822a54f2
commit a0fad6065a
21 changed files with 2263 additions and 97 deletions

View 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,
}
}
}

View 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()
}
}

View 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
}
}

View 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())
}
}

View 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;

View 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,
}
}
}

View 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())?)
}
}