feat: add publish, and rpc
This commit is contained in:
1
__enclave/virt_enclave/.gitignore
vendored
1
__enclave/virt_enclave/.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
|
js/
|
||||||
platform_signing_key.json
|
platform_signing_key.json
|
||||||
|
|||||||
1143
__enclave/virt_enclave/Cargo.lock
generated
1143
__enclave/virt_enclave/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -13,4 +13,6 @@ hex = "0.4"
|
|||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
rust_util = "0.6"
|
rust_util = "0.6"
|
||||||
|
lazy_static = "1.4"
|
||||||
|
tokio = { version = "0.2", features = ["full"] }
|
||||||
|
warp = "0.2"
|
||||||
|
|||||||
33
__enclave/virt_enclave/README.md
Normal file
33
__enclave/virt_enclave/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
Init signing key:
|
||||||
|
```shell
|
||||||
|
$ cargo r --example create_signing_key
|
||||||
|
```
|
||||||
|
|
||||||
|
Publish script:
|
||||||
|
```shell
|
||||||
|
$ cargo r --example publish_js sample.js
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ curl localhost:8888/get_signing_public_key
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ curl localhost:8888/list_js
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ curl localhost:8888/get_js/30dfa248a807d35820416228c09b983a940f75247eb0cfdfc03ed12e92f58ba6
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ curl -X POST -H 'Content-Type: application/json' \
|
||||||
|
--data '{"method": "getName"}' \
|
||||||
|
localhost:8888/call_js/30dfa248a807d35820416228c09b983a940f75247eb0cfdfc03ed12e92f58ba6
|
||||||
|
```
|
||||||
|
|
||||||
|
`--data '{"method": "getName"}'` can be replaced by: `--data-binary @file.json`
|
||||||
|
|
||||||
34
__enclave/virt_enclave/examples/publish_js.rs
Normal file
34
__enclave/virt_enclave/examples/publish_js.rs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
use std::io::{ Read, Write };
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::Path;
|
||||||
|
use ring::digest;
|
||||||
|
use virt_enclave::sig::*;
|
||||||
|
use rust_util::XResult;
|
||||||
|
|
||||||
|
fn main() -> XResult<()> {
|
||||||
|
let mut args = std::env::args();
|
||||||
|
args.next();
|
||||||
|
let signing_key_pair = virt_enclave::util::load_signing_key_pair().expect("Load singing key pair!");
|
||||||
|
let f = args.next().ok_or_else(|| rust_util::new_box_error("File not assigned!"))?;
|
||||||
|
let mut file = File::open(&f)?;
|
||||||
|
let mut buf = vec![];
|
||||||
|
file.read_to_end(&mut buf)?;
|
||||||
|
let d = digest::digest(&digest::SHA256, &buf);
|
||||||
|
let digest_hex = hex::encode(&d);
|
||||||
|
let mut signed_message = SignedMessage::new(d.as_ref().to_vec(), None);
|
||||||
|
signed_message.sign(&signing_key_pair);
|
||||||
|
|
||||||
|
let js_path = Path::new("js");
|
||||||
|
if !js_path.exists() {
|
||||||
|
std::fs::create_dir(js_path).expect("Create js/ dir");
|
||||||
|
}
|
||||||
|
|
||||||
|
let js_file = format!("js/{}.js", digest_hex);
|
||||||
|
let js_sign_file = format!("js/{}.sig.json", digest_hex);
|
||||||
|
|
||||||
|
File::create(&js_file)?.write_all(&buf).expect("Write js/HEX.js file");
|
||||||
|
println!("Write file successed: {}", js_file);
|
||||||
|
File::create(&js_sign_file)?.write_all(serde_json::to_string(&signed_message)?.as_bytes()).expect("Write js/HEX.sig.json file");
|
||||||
|
println!("Write file successed: {}", js_sign_file);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
7
__enclave/virt_enclave/sample.js
Normal file
7
__enclave/virt_enclave/sample.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
function __EXPORT(f) { eval('__PUBLIC_' + f + '=' + f); }
|
||||||
|
|
||||||
|
function getName() {
|
||||||
|
return 'This is hatter!';
|
||||||
|
}
|
||||||
|
|
||||||
|
__EXPORT('getName');
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
pub mod qjs;
|
pub mod qjs;
|
||||||
pub mod sig;
|
pub mod sig;
|
||||||
pub mod rpc;
|
pub mod rpc;
|
||||||
|
pub mod util;
|
||||||
|
|||||||
@@ -1,43 +1,113 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use warp::Filter;
|
||||||
|
use serde::{ Serialize, Deserialize };
|
||||||
|
|
||||||
include!("lib.rs");
|
include!("lib.rs");
|
||||||
|
|
||||||
pub use qjs::*;
|
pub use qjs::*;
|
||||||
pub use sig::*; // TODO
|
pub use sig::*;
|
||||||
pub use rpc::*;
|
pub use rpc::*;
|
||||||
|
pub use util::*;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
let get_public_key = warp::path("get_signing_public_key").map(|| {
|
||||||
|
match get_signing_public_key() {
|
||||||
|
None => "null".to_owned(),
|
||||||
|
Some(public_key) => {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert("public_key", hex::encode(&public_key));
|
||||||
|
serde_json::to_string_pretty(&map).unwrap_or_else(|e| format!("get public key error: {}", e))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let list_js = warp::path("list_js").map(|| {
|
||||||
|
let mut jss = vec![];
|
||||||
|
if let Ok(read_dir) = std::fs::read_dir("js") {
|
||||||
|
for entry in read_dir {
|
||||||
|
if let Ok(dir_entry) = entry {
|
||||||
|
if let Ok(file_name) = dir_entry.file_name().into_string() {
|
||||||
|
if file_name.ends_with(".js") {
|
||||||
|
let chars = file_name.chars();
|
||||||
|
jss.push(chars.take(file_name.chars().count() - 3).collect::<String>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serde_json::to_string_pretty(&jss).unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
let get_js = warp::path!("get_js" / String).map(|js_hex| {
|
||||||
|
let js_fn = format!("js/{}.js", js_hex);
|
||||||
|
let js_sig_fn = format!("js/{}.sig.json", js_hex);
|
||||||
|
let js = read_file(&js_fn).unwrap();
|
||||||
|
let js_sig = read_file(&js_sig_fn).unwrap();
|
||||||
|
|
||||||
|
let signed_message: SignedMessage = serde_json::from_str(&js_sig).unwrap();
|
||||||
|
|
||||||
|
let mut result = HashMap::new();
|
||||||
|
result.insert("js", js);
|
||||||
|
result.insert("sig", js_sig);
|
||||||
|
result.insert("verify", signed_message.verify(&load_signing_key_pair().unwrap().public_key()).to_string());
|
||||||
|
|
||||||
|
serde_json::to_string(&result).unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
let call_js = warp::post()
|
||||||
|
.and(warp::path!("call_js" / String))
|
||||||
|
.and(warp::body::json())
|
||||||
|
.map(|js_hex, call_js_body: CallJSBody| {
|
||||||
|
let js_fn = format!("js/{}.js", js_hex);
|
||||||
|
let js_sig_fn = format!("js/{}.sig.json", js_hex);
|
||||||
|
let js = read_file(&js_fn).unwrap();
|
||||||
|
let js_sig = read_file(&js_sig_fn).unwrap();
|
||||||
|
|
||||||
|
let signed_message: SignedMessage = serde_json::from_str(&js_sig).unwrap();
|
||||||
|
if !signed_message.verify(&load_signing_key_pair().unwrap().public_key()) {
|
||||||
|
let mut result = HashMap::new();
|
||||||
|
result.insert("status", "400".to_owned());
|
||||||
|
result.insert("message", "Script verify failed!".to_owned());
|
||||||
|
result.insert("js_hash", format!("{}", js_hex));
|
||||||
|
return serde_json::to_string(&result).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let context = QuickJSContext::new().unwrap();
|
let context = QuickJSContext::new().unwrap();
|
||||||
|
context.init(&js).unwrap();
|
||||||
|
|
||||||
let script = r##"
|
let r = context.call_fn(&call_js_body.method, &call_js_body.params.unwrap_or_else(|| "[]".to_owned()));
|
||||||
function __EXPORT(f) { eval('__PUBLIC_' + f + '=' + f); }
|
|
||||||
|
|
||||||
function getName() {
|
let mut result = HashMap::new();
|
||||||
console.info("=========================");
|
result.insert("js_hash", format!("{}", js_hex));
|
||||||
for (var i = 0; i < arguments.length; i++) {
|
match r {
|
||||||
console.info(i, ' ----> ', arguments[i]);
|
Err(e) => {
|
||||||
}
|
result.insert("status", "500".to_owned());
|
||||||
return 'hatter';
|
result.insert("message", "Script call failed!".to_owned());
|
||||||
}
|
result.insert("result", format!("{}", e));
|
||||||
function helloAb(a, b) {
|
},
|
||||||
console.info("Hello: ", a);
|
Ok(r) => {
|
||||||
console.info("Hello: ", b);
|
result.insert("status", "200".to_owned());
|
||||||
}
|
result.insert("message", "Script call successed!".to_owned());
|
||||||
function main(p) {
|
result.insert("result", r.into_string().unwrap_or_else(|| "null".to_owned()));
|
||||||
console.log(p);
|
},
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
return serde_json::to_string(&result).unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
__EXPORT('getName');
|
println!("Listen at 127.0.0.1:8888 ...");
|
||||||
__EXPORT('helloAb');
|
warp::serve(
|
||||||
"##;
|
get_public_key.or(list_js)
|
||||||
|
.or(get_js)
|
||||||
context.init(script).unwrap();
|
.or(call_js)
|
||||||
// let mut map = HashMap::new();
|
)
|
||||||
// map.insert("name", "hatter");
|
.run(([127, 0, 0, 1], 8888))
|
||||||
// let r = context.run_js(&map);
|
.await;
|
||||||
// println!("{:?}", r);
|
}
|
||||||
let r = context.call_fn("getName", "[1, 'hatter', 'jiang']");
|
|
||||||
println!("{:?}", r);
|
#[derive(Serialize, Deserialize)]
|
||||||
let r = context.call_fn("helloAb", "['hatter', 'jiang']");
|
struct CallJSBody {
|
||||||
println!("{:?}", r);
|
method: String,
|
||||||
|
params: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use ring::{
|
|||||||
};
|
};
|
||||||
use rust_util::XResult;
|
use rust_util::XResult;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct SigningKeyPair {
|
pub struct SigningKeyPair {
|
||||||
key_pair: Vec<u8>,
|
key_pair: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|||||||
23
__enclave/virt_enclave/src/util.rs
Normal file
23
__enclave/virt_enclave/src/util.rs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use crate::sig::SigningKeyPair;
|
||||||
|
use rust_util::XResult;
|
||||||
|
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
static ref SIGNING_KEY_PAIR: Option<SigningKeyPair> = load_signing_key_pair();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_signing_public_key() -> Option<String> {
|
||||||
|
SIGNING_KEY_PAIR.as_ref().map(|key_pair| hex::encode(&key_pair.public_key()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_signing_key_pair() -> Option<SigningKeyPair> {
|
||||||
|
SigningKeyPair::read_from_file("platform_signing_key.json").ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_file(f: &str) -> XResult<String> {
|
||||||
|
let mut file = File::open(&f).map_err(|e| rust_util::new_box_error(&format!("Open file: {}, failed: {}", f , e)))?;
|
||||||
|
let mut buf = String::new();
|
||||||
|
file.read_to_string(&mut buf).map_err(|e| rust_util::new_box_error(&format!("Read file: {}, failed: {}", f , e)))?;
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user