Skip to content

Commit

Permalink
feat: Generalised resource manager (#340)
Browse files Browse the repository at this point in the history
* add initial resource manager

* add `ApplicationResourceManager` struct

* update resource manager implementations, update crypto runtime extensions with the usage of new resource manager struct

* refactor

* fix spelling

* fix

* wip

* update Sqlite state handling

* add resource manager tests, fix issue

* refactor resource manager interface

* wip

* update resource manager interface

* add InputStreams state

* fix input streams state initialization

* add output streams state

* add usage of output streams

* refactor preopen dir state

* refactor fs descriptors state

* refactor resource manager api

* fix deadlock issue

* update docs

* cleanup

* fix spelling

* rename resource manager to resource storage
  • Loading branch information
Mr-Leshiy authored Aug 26, 2024
1 parent 175432d commit e66b40e
Show file tree
Hide file tree
Showing 22 changed files with 529 additions and 1,014 deletions.
5 changes: 0 additions & 5 deletions hermes/bin/src/runtime_extensions/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,4 @@ use wasmtime::component::bindgen;
bindgen!({
world: "hermes",
path: "../../wasm/wasi/wit",
with: {
"wasi:filesystem/types/descriptor": super::wasi::descriptors::Descriptor,
"wasi:io/streams/input-stream": super::wasi::descriptors::Stream,
"wasi:io/streams/output-stream": super::wasi::descriptors::Stream,
}
});
104 changes: 38 additions & 66 deletions hermes/bin/src/runtime_extensions/hermes/crypto/host.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
//! Crypto host implementation for WASM runtime.
use wasmtime::component::Resource;

use super::bip32_ed25519::check_signature;
use super::{
bip32_ed25519::{check_signature, derive_new_private_key, get_public_key, sign_data},
bip39::{generate_new_mnemonic, mnemonic_to_xprv},
state::get_state,
};
use crate::{
runtime_context::HermesRuntimeContext,
runtime_extensions::{
bindings::hermes::{
binary::api::Bstr,
crypto::api::{
Bip32Ed25519, Bip32Ed25519PublicKey, Bip32Ed25519Signature, Errno, Host,
HostBip32Ed25519, MnemonicPhrase, Passphrase, Path,
},
},
hermes::crypto::{
bip32_ed25519::{derive_new_private_key, get_public_key, sign_data},
bip39::{generate_new_mnemonic, mnemonic_to_xprv},
state::{add_resource, delete_resource, get_resource},
runtime_extensions::bindings::hermes::{
binary::api::Bstr,
crypto::api::{
Bip32Ed25519, Bip32Ed25519PublicKey, Bip32Ed25519Signature, Errno, Host,
HostBip32Ed25519, MnemonicPhrase, Passphrase, Path,
},
},
};
Expand All @@ -32,35 +27,22 @@ impl HostBip32Ed25519 for HermesRuntimeContext {
&mut self, mnemonic: MnemonicPhrase, passphrase: Option<Passphrase>,
) -> wasmtime::Result<wasmtime::component::Resource<Bip32Ed25519>> {
let passphrase = passphrase.unwrap_or_default();
let xprv = mnemonic_to_xprv(&mnemonic.join(" "), &passphrase.join(" "));
match xprv {
Ok(xprv) => {
if let Some(id) = add_resource(self.app_name(), xprv) {
Ok(Resource::new_own(id))
} else {
// TODO(bkioshn): https://github.com/input-output-hk/hermes/issues/183
Err(wasmtime::Error::msg("Error creating new resource"))
}
},
Err(e) => Err(wasmtime::Error::msg(e.to_string())),
}
// TODO(bkioshn): https://github.com/input-output-hk/hermes/issues/183
let xprv = mnemonic_to_xprv(&mnemonic.join(" "), &passphrase.join(" "))
.map_err(|e| wasmtime::Error::msg(e.to_string()))?;

let app_state = get_state().get_app_state(self.app_name())?;
Ok(app_state.create_resource(xprv))
}

/// Get the public key for this private key.
fn public_key(
&mut self, resource: wasmtime::component::Resource<Bip32Ed25519>,
) -> wasmtime::Result<Bip32Ed25519PublicKey> {
let private_key = get_resource(self.app_name(), resource.rep());
match private_key {
Some(private_key) => {
let public_key = get_public_key(&private_key);
Ok(public_key)
},
None => {
// TODO(bkioshn): https://github.com/input-output-hk/hermes/issues/183
Ok((0, 0, 0, 0))
},
}
let mut app_state = get_state().get_app_state(self.app_name())?;
let private_key = app_state.get_object(&resource)?;
let public_key = get_public_key(&private_key);
Ok(public_key)
}

/// Sign data with the Private key, and return it.
Expand All @@ -71,15 +53,10 @@ impl HostBip32Ed25519 for HermesRuntimeContext {
fn sign_data(
&mut self, resource: wasmtime::component::Resource<Bip32Ed25519>, data: Bstr,
) -> wasmtime::Result<Bip32Ed25519Signature> {
let private_key = get_resource(self.app_name(), resource.rep());
match private_key {
Some(private_key) => {
let sig = sign_data(&private_key, &data);
Ok(sig)
},
// TODO(bkioshn): https://github.com/input-output-hk/hermes/issues/183
None => Ok((0, 0, 0, 0, 0, 0, 0, 0)),
}
let mut app_state = get_state().get_app_state(self.app_name())?;
let private_key = app_state.get_object(&resource)?;
let sig = sign_data(&private_key, &data);
Ok(sig)
}

/// Check a signature on a set of data.
Expand All @@ -97,15 +74,10 @@ impl HostBip32Ed25519 for HermesRuntimeContext {
&mut self, resource: wasmtime::component::Resource<Bip32Ed25519>, data: Bstr,
sig: Bip32Ed25519Signature,
) -> wasmtime::Result<bool> {
let private_key = get_resource(self.app_name(), resource.rep());
match private_key {
Some(private_key) => {
let check_sig = check_signature(&private_key, &data, sig);
Ok(check_sig)
},
// TODO(bkioshn): https://github.com/input-output-hk/hermes/issues/183
None => Ok(false),
}
let mut app_state = get_state().get_app_state(self.app_name())?;
let private_key = app_state.get_object(&resource)?;
let check_sig = check_signature(&private_key, &data, sig);
Ok(check_sig)
}

/// Derive a new private key from the current private key.
Expand All @@ -118,19 +90,19 @@ impl HostBip32Ed25519 for HermesRuntimeContext {
fn derive(
&mut self, resource: wasmtime::component::Resource<Bip32Ed25519>, path: Path,
) -> wasmtime::Result<wasmtime::component::Resource<Bip32Ed25519>> {
get_resource(self.app_name(), resource.rep())
.and_then(|private_key| derive_new_private_key(private_key, &path).ok())
.and_then(|derived_private_key| add_resource(self.app_name(), derived_private_key))
.map(Resource::new_own)
// TODO(bkioshn): https://github.com/input-output-hk/hermes/issues/183
.ok_or_else(|| wasmtime::Error::msg("Error deriving new private key"))
let mut app_state = get_state().get_app_state(self.app_name())?;

let private_key = app_state.get_object(&resource)?;
// TODO(bkioshn): https://github.com/input-output-hk/hermes/issues/183
let new_private_key = derive_new_private_key(private_key.clone(), &path)
.map_err(|_| wasmtime::Error::msg("Error deriving new private key"))?;
drop(private_key);
Ok(app_state.create_resource(new_private_key))
}

fn drop(&mut self, res: wasmtime::component::Resource<Bip32Ed25519>) -> wasmtime::Result<()> {
// If the state deletion is successful, drop the resource.
if delete_resource(self.app_name(), res.rep()).is_some() {
let _unused = self.drop(res);
}
let app_state = get_state().get_app_state(self.app_name())?;
app_state.delete_resource(res)?;
Ok(())
}
}
Expand Down
8 changes: 1 addition & 7 deletions hermes/bin/src/runtime_extensions/hermes/crypto/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
//! Crypto runtime extension implementation.
use self::state::{get_state, set_state};

mod bip32_ed25519;
mod bip39;
mod host;
mod state;

/// Advise Runtime Extensions of a new context
pub(crate) fn new_context(ctx: &crate::runtime_context::HermesRuntimeContext) {
// check whether it exist
let state = get_state();
if !state.contains_key(ctx.app_name()) {
set_state(ctx.app_name().clone());
}
state::get_state().add_app(ctx.app_name().clone());
}
Loading

0 comments on commit e66b40e

Please sign in to comment.