feat: can run qjs
This commit is contained in:
@@ -1,5 +1,46 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
mod qjs;
|
||||
mod sig;
|
||||
|
||||
pub use qjs::*;
|
||||
pub use sig::*; // TODO
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
let context = QuickJSContext::new().unwrap();
|
||||
|
||||
let mut map = HashMap::new();
|
||||
map.insert("name", "hatter");
|
||||
|
||||
let script = r##"
|
||||
function __EXPORT(f) { eval('__PUBLIC_' + f + '=' + f); }
|
||||
|
||||
function getName() {
|
||||
console.info("=========================");
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
console.info(i, ' ----> ', arguments[i]);
|
||||
}
|
||||
return 'hatter';
|
||||
}
|
||||
function helloAb(a, b) {
|
||||
console.info("Hello: ", a);
|
||||
console.info("Hello: ", b);
|
||||
}
|
||||
function main(p) {
|
||||
console.log(p);
|
||||
return 1;
|
||||
}
|
||||
|
||||
__EXPORT('getName');
|
||||
__EXPORT('helloAb');
|
||||
"##;
|
||||
|
||||
context.init(script).unwrap();
|
||||
let r = context.run_js(&map);
|
||||
println!("{:?}", r);
|
||||
let r = context.call_fn("getName", "[1, 'hatter', 'jiang']");
|
||||
println!("{:?}", r);
|
||||
let r = context.call_fn("helloAb", "['hatter', 'jiang']");
|
||||
println!("{:?}", r);
|
||||
}
|
||||
|
||||
|
||||
65
__enclave/virt_enclave/src/qjs.rs
Normal file
65
__enclave/virt_enclave/src/qjs.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
use quick_js::Context;
|
||||
use quick_js::JsValue;
|
||||
use quick_js::console::Level;
|
||||
use quick_js::console::ConsoleBackend;
|
||||
use serde::{ Serialize, Deserialize };
|
||||
use rust_util::XResult;
|
||||
|
||||
pub struct QuickJSContext {
|
||||
context: Context,
|
||||
}
|
||||
|
||||
impl QuickJSContext {
|
||||
pub fn new() -> XResult<Self> {
|
||||
Ok(Self{
|
||||
context: build_default_context()?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn init(&self, js: &str) -> XResult<JsValue> {
|
||||
self.context.eval(js).map_err(|e| e.into())
|
||||
}
|
||||
|
||||
pub fn run_js<T>(&self, p: &T) -> XResult<JsValue> where T: ?Sized + Serialize {
|
||||
let p_json = match serde_json::to_string(p) {
|
||||
Err(e) => return Err(e.into()),
|
||||
Ok(p) => p,
|
||||
};
|
||||
self.context.eval(&format!("main({})", p_json)).map_err(|e| e.into())
|
||||
}
|
||||
|
||||
pub fn call_fn(&self, fun: &str, params: &str) -> XResult<JsValue> {
|
||||
if !params.trim().starts_with("[") {
|
||||
return Err(rust_util::new_box_error("Params is not JSON array!"));
|
||||
}
|
||||
let f: String = fun.chars().map(|c| if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' {
|
||||
c
|
||||
} else {
|
||||
'_'
|
||||
}).collect();
|
||||
|
||||
// TODO check JSON valid
|
||||
// let v: Option<Vec<EmptyObject>> = serde_json::from_str(params).ok();
|
||||
// if v.is_none() {
|
||||
// return Err(rust_util::new_box_error("Params is not valid JSON array!"));
|
||||
// }
|
||||
self.context.eval(&format!("__PUBLIC_{}.apply(null, {})", f, params)).map_err(|e| e.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct EmptyObject {}
|
||||
|
||||
struct ConsoleBackendImpl;
|
||||
impl ConsoleBackend for ConsoleBackendImpl {
|
||||
fn log(&self, level: Level, values: Vec<JsValue>) {
|
||||
println!("[{:>5}] - {:?}", format!("{:?}", level).to_uppercase(), values);
|
||||
}
|
||||
}
|
||||
|
||||
fn build_default_context() -> XResult<Context> {
|
||||
Context::builder().memory_limit(16 * 1024 * 1024)
|
||||
.console(ConsoleBackendImpl{})
|
||||
.build()
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
@@ -3,8 +3,8 @@ use std::io::{ Write, Read };
|
||||
use serde::{ Deserialize, Serialize };
|
||||
use ring::{
|
||||
signature::{ KeyPair, Ed25519KeyPair, UnparsedPublicKey, ED25519 },
|
||||
hmac, rand, error::Unspecified,
|
||||
digest,
|
||||
rand,
|
||||
// hmac, digest, error::Unspecified,
|
||||
};
|
||||
use rust_util::XResult;
|
||||
|
||||
@@ -14,7 +14,7 @@ pub struct SigningKeyPair {
|
||||
}
|
||||
|
||||
impl SigningKeyPair {
|
||||
fn new() -> Self {
|
||||
pub fn new() -> Self {
|
||||
let rng = rand::SystemRandom::new();
|
||||
let pkcs8 = Ed25519KeyPair::generate_pkcs8(&rng).unwrap(); // TODO ...
|
||||
SigningKeyPair{
|
||||
@@ -22,19 +22,19 @@ impl SigningKeyPair {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse(&self) -> Ed25519KeyPair {
|
||||
pub fn key_pair(&self) -> Ed25519KeyPair {
|
||||
Ed25519KeyPair::from_pkcs8(&self.key_pair).unwrap() // TODO ...
|
||||
}
|
||||
|
||||
fn public_key(&self) -> Vec<u8> {
|
||||
self.parse().public_key().as_ref().to_vec()
|
||||
pub fn public_key(&self) -> Vec<u8> {
|
||||
self.key_pair().public_key().as_ref().to_vec()
|
||||
}
|
||||
|
||||
fn unparsed_public_key(&self) -> UnparsedPublicKey<Vec<u8>> {
|
||||
pub fn unparsed_public_key(&self) -> UnparsedPublicKey<Vec<u8>> {
|
||||
UnparsedPublicKey::new(&ED25519, self.public_key())
|
||||
}
|
||||
|
||||
fn read_from_file(file: &str) -> XResult<Self> {
|
||||
pub fn read_from_file(file: &str) -> XResult<Self> {
|
||||
match File::open(file) {
|
||||
Err(e) => Err(rust_util::new_box_ioerror(&format!("Read from file failed: {}", e))),
|
||||
Ok(mut f) => {
|
||||
@@ -53,7 +53,7 @@ impl SigningKeyPair {
|
||||
}
|
||||
}
|
||||
|
||||
fn write_to_file(&self, file: &str) -> XResult<()> {
|
||||
pub fn write_to_file(&self, file: &str) -> XResult<()> {
|
||||
if File::open(file).is_ok() {
|
||||
return Err(rust_util::new_box_ioerror(&format!("File exists: {}", file)));
|
||||
}
|
||||
@@ -90,7 +90,7 @@ impl SignedMessage {
|
||||
}
|
||||
|
||||
pub fn sign(&mut self, key_pair: &SigningKeyPair) {
|
||||
let sig = key_pair.parse().sign(&self.msg);
|
||||
let sig = key_pair.key_pair().sign(&self.msg);
|
||||
self.sig = Some(sig.as_ref().to_vec());
|
||||
}
|
||||
|
||||
@@ -113,4 +113,4 @@ fn test_sign() {
|
||||
);
|
||||
signed_message.sign(&signing_key_pair);
|
||||
assert!(signed_message.verify(&signing_key_pair.public_key()))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user