Merge 'lox-wasm/main' into lox-workspace

This commit is contained in:
onyinyang 2023-06-05 15:12:26 -04:00
commit a0a859820a
No known key found for this signature in database
GPG Key ID: 156A6435430C2036
7 changed files with 960 additions and 0 deletions

2
crates/lox-wasm/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target/*
Cargo.lock

View File

@ -0,0 +1,30 @@
[package]
name = "lox-wasm"
authors = ["Cecylia Bocovich <cohosh@torproject.org>"]
version = "0.1.0"
edition = "2021"
description = "WASM bindings for lox"
license = "MIT"
[lib]
crate-type = ["cdylib"]
[dependencies]
julianday = "1.2.0"
lazy_static = "1.4.0"
lox = { git = "https://gitlab.torproject.org/onyinyang/lox.git", branch = "master" }
wasm-bindgen = "0.2"
time = "0.2"
serde_json = "1.0.87"
serde = "1"
serde_with = "1.9.1"
serde-wasm-bindgen = "0.4.5"
console_error_panic_hook = "0.1.7"
js-sys = "0.3.61"
rand = { version = "0.7", features = ["wasm-bindgen"] }
zkp = "0.8.0"
[dependencies.chrono]
version = "0.4.19"
features = ["serde", "wasmbind"]

21
crates/lox-wasm/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Cecylia Bocovich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

26
crates/lox-wasm/README.md Normal file
View File

@ -0,0 +1,26 @@
# lox-wasm
wasm bindings for the lox crate: https://git-crysp.uwaterloo.ca/iang/lox
# Dependencies
```
cargo install wasm-pack
```
# Build
```
wasm-pack build --target web
```
# Testing
The provided `index.html` file can be used for testing the lox bindings. First, follow the instructions to [run a lox server](https://gitlab.torproject.org/cohosh/lox-server).
Then, spin up a simple local webserver in the current directory:
```
python3 -m http.server 8000
```
Next, open the dev console in your browser and navigate to `http://localhost:8000`.

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>Lox binding test</title>
</head>
<body>
<script type="module" src="index.js"></script>
</body>
</html>

241
crates/lox-wasm/index.js Normal file
View File

@ -0,0 +1,241 @@
import init, {
open_invite,
handle_new_lox_credential,
trust_promotion,
handle_trust_promotion,
trust_migration,
handle_trust_migration,
level_up,
handle_level_up,
issue_invite,
handle_issue_invite,
prepare_invite,
redeem_invite,
handle_redeem_invite,
check_blockage,
handle_check_blockage,
blockage_migration,
handle_blockage_migration,
set_panic_hook } from "./pkg/lox_wasm.js";
let pubkeys = await simple_request("/pubkeys");
console.log("Got pubkeys: " + pubkeys);
// Get Lox Invitation
let requested_invite = await init().then(() => {
set_panic_hook();
let requested_invite = request_open_invite().then((token) => {
return open_invite(token);
});
return requested_invite;
});
console.log("Got request and state: "+requested_invite);
// Redeem Lox Invitation for an Open Invitation Lox Credential
// Trust Level 0
let open_lox_cred = await init().then(() => {
set_panic_hook();
let cred = requested_cred("/openreq", requested_invite).then((response) => {
console.log("Got new Level 0 Lox Credential: " + response);
return handle_new_lox_credential(requested_invite, response, pubkeys);
});
return cred;
});
let requested_trust_promo = trust_promotion(open_lox_cred, pubkeys);
// Get Migration credential for Trust Promotion from Trust Level 0 -> 1
let trust_promo_cred = await init().then(() => {
set_panic_hook();
let cred = requested_cred("/trustpromo", requested_trust_promo).then((response)=> {
console.log("Got Migration Credential for Trust Promotion: " + response);
return handle_trust_promotion(requested_trust_promo, response);
});
return cred;
});
let requested_trust_migration = trust_migration(open_lox_cred, trust_promo_cred, pubkeys);
// Trust Promotion from Trust Level 0 -> 1
let lox_cred = await init().then(() => {
set_panic_hook();
let cred = requested_cred("/trustmig", requested_trust_migration).then((response)=> {
console.log("Got new Level 1 Lox Credential: " + response);
return handle_trust_migration(requested_trust_migration, response, pubkeys);
});
return cred;
});
let encrypted_table = await simple_request("/reachability");
console.log("Got Encrypted Table: " + encrypted_table);
let requested_level_two = level_up(lox_cred, encrypted_table, pubkeys);
// Level Up to Trust Level 2
lox_cred = await init().then(() => {
set_panic_hook();
let cred = requested_cred("/levelup", requested_level_two).then((response)=> {
console.log("Got new Level 2 Lox Credential: " + response);
return handle_level_up(requested_level_two, response, pubkeys);
});
return cred;
});
// Update reachability cred
encrypted_table = await simple_request("/reachability");
console.log("Got Encrypted Table: " + encrypted_table);
let requested_level_three = level_up(lox_cred, encrypted_table, pubkeys);
// Level Up to Trust Level 3
lox_cred = await init().then(() => {
set_panic_hook();
let cred = requested_cred("/levelup", requested_level_three).then((response)=> {
console.log("Got new Level 3 Lox Credential: " + response);
return handle_level_up(requested_level_three, response, pubkeys);
});
return cred;
});
// Update reachability cred
encrypted_table = await simple_request("/reachability");
console.log("Got Encrypted Table: " + encrypted_table);
let requested_level_four = level_up(lox_cred, encrypted_table, pubkeys);
// Level Up to Trust Level 4
lox_cred = await init().then(() => {
set_panic_hook();
let cred = requested_cred("/levelup", requested_level_four).then((response)=> {
console.log("Got new Level 4 Lox Credential: " + response);
return handle_level_up(requested_level_four, response, pubkeys);
});
return cred;
});
// Update reachability cred
encrypted_table = await simple_request("/reachability");
console.log("Got Encrypted Table: " + encrypted_table);
let requested_issue_invitation = issue_invite(lox_cred, encrypted_table, pubkeys);
// Issue an Invitation cred
lox_cred = await init().then(() => {
set_panic_hook();
let cred = requested_cred("/issueinvite", requested_issue_invitation).then((response)=> {
console.log("Got new Invite and Lox Credential: " + response);
return handle_issue_invite(requested_issue_invitation, response, pubkeys);
});
return cred;
});
let prepared_invitation = prepare_invite(lox_cred);
// Trusted Invitation Request
let requested_invitation = redeem_invite(prepared_invitation, pubkeys);
// Redeem an Invitation cred
let lox_cred_from_invite = await init().then(() => {
set_panic_hook();
let cred = requested_cred("/redeem", requested_invitation).then((response)=> {
console.log("Got new Trusted Lox Credential Invite: " + response);
return handle_redeem_invite(requested_invitation, response, pubkeys);
});
return cred;
});
let requested_check_blockage = check_blockage(lox_cred, pubkeys);
// Check whether or not a bucket is blocked
let check_migration_cred = await init().then(() => {
set_panic_hook();
let cred = requested_cred("/checkblockage", requested_check_blockage).then((response)=> {
console.log("Got check blockage Migration Credential: " + response);
return handle_check_blockage(requested_check_blockage, response);
});
return cred;
});
let requested_blockage_migration = blockage_migration(lox_cred, check_migration_cred, pubkeys);
// Migrate to a new unblocked bridge
lox_cred = await init().then(() => {
set_panic_hook();
let cred = requested_cred("/blockagemigration", requested_blockage_migration).then((response)=> {
console.log("Got Lox Credential for new bucket: " + response);
return handle_blockage_migration(requested_blockage_migration, response, pubkeys);
});
return cred;
});
function requested_cred(command, requested) {
return new Promise((fulfill, reject) => {
let req = JSON.parse(requested);
loxServerPostRequest(command, req.request).then((response) => {
fulfill(JSON.stringify(response));
return;
}).catch(() => {
console.log("Error requesting new Lox credential from server");
reject();
});
});
}
function request_open_invite() {
return new Promise((fulfill, reject) => {
loxServerPostRequest("/invite", null).then((response) => {
console.log("Got invitation token: " + response.invite);
fulfill(response.invite);
return;
}).catch(() => {
console.log("Error requesting open invite from Lox server");
reject();
});
});
}
function simple_request(requested) {
return new Promise((fulfill, reject) => {
loxServerPostRequest(requested, null).then((response) => {
fulfill(JSON.stringify(response));
return;
}).catch(() => {
console.log("Error making simple request: " + requested);
reject();
});
});
}
function loxServerPostRequest(data, payload) {
return new Promise((fulfill, reject) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.DONE !== xhr.readyState) {
return;
}
if (xhr.status !== 200) {
console.log("Error. Status code: "+xhr.status);
console.log(xhr);
reject();
return;
}
const response = JSON.parse(xhr.responseText);
fulfill(response);
return;
};
try {
xhr.open('POST', "http://localhost:8001"+data, true)
xhr.setRequestHeader("Content-Type", "application/json");
} catch (err) {
console.log("Error connecting to lox bridge db");
reject();
return;
}
xhr.send(JSON.stringify(payload));
});
}
// The correct key should be matched against a public commit to the key to
// verify that the key issuer is in fact the correct Bridge Authority
function loxKeyRequest(key_type) {
return new Promise((fulfull, reject) => {
})
}

629
crates/lox-wasm/src/lib.rs Normal file
View File

@ -0,0 +1,629 @@
use chrono::{Duration, Utc};
use julianday::JulianDay;
use lox::bridge_table::{BridgeLine,from_scalar,BridgeTable, ENC_BUCKET_BYTES};
use lox::cred::{BucketReachability, Invitation, Lox, Migration};
use lox::proto::{open_invite, trust_promotion, migration, level_up,
issue_invite, redeem_invite, check_blockage, blockage_migration};
use lox::{IssuerPubKey, OPENINV_LENGTH, scalar_u32};
use serde::{Deserialize, Serialize};
use serde_with::{serde_as};
use std::array::TryFromSliceError;
use std::{panic};
use wasm_bindgen::prelude::*;
use zkp::ProofError;
#[derive(Deserialize, Serialize)]
struct OpenReqState {
request: open_invite::Request,
state: open_invite::State,
}
#[derive(Deserialize, Serialize)]
struct TrustReqState {
request: trust_promotion::Request,
state: trust_promotion::State,
}
#[derive(Deserialize, Serialize)]
struct MigReqState {
request: migration::Request,
state: migration::State,
}
#[derive(Deserialize, Serialize)]
struct LevelupReqState {
request: level_up::Request,
state: level_up::State,
}
#[derive(Deserialize, Serialize)]
struct IssueInviteReqState {
request: issue_invite::Request,
state: issue_invite::State,
}
#[derive(Deserialize, Serialize)]
struct RedeemReqState {
request: redeem_invite::Request,
state: redeem_invite::State,
}
#[derive(Deserialize, Serialize)]
struct CheckBlockageReqState {
request: check_blockage::Request,
state: check_blockage::State,
}
#[derive(Deserialize, Serialize)]
struct BlockageMigReqState {
request: blockage_migration::Request,
state: blockage_migration::State,
}
#[derive(Debug, Deserialize, Serialize)]
struct PubKeys {
lox_pub: IssuerPubKey,
migration_pub: IssuerPubKey,
migrationkey_pub: IssuerPubKey,
reachability_pub: IssuerPubKey,
invitation_pub: IssuerPubKey,
}
#[serde_as]
#[derive(Serialize, Deserialize)]
pub struct EncBridgeTable {
#[serde_as(as = "Vec<[_; ENC_BUCKET_BYTES]>")]
pub etable: Vec<[u8; ENC_BUCKET_BYTES]>,
}
#[derive(Debug, Deserialize, Serialize)]
struct LoxCredential {
lox_credential: Lox,
bridgeline: Option<BridgeLine>,
invitation: Option<Invitation>,
}
fn today() -> u32 {
let naive_now = Utc::now().date_naive();
JulianDay::from(naive_now).inner().try_into().unwrap()
}
// This should only be used for testing, use today in production
fn test_today(days: i64) -> u32 {
let naive_now_plus = (Utc::now() + Duration::days(days)).date_naive();
JulianDay::from(naive_now_plus).inner().try_into().unwrap()
}
//pub const MAX_LEVEL: usize = 4;
//pub const LEVEL_INTERVAL: [u32; MAX_LEVEL + 1] = [0, 14, 28, 56, 84];
fn calc_test_days(lox_cred: &Lox) -> Result<i64, ProofError> {
let trust_level: i64 = match scalar_u32(&lox_cred.trust_level) {
Some(v) => v as i64,
None => return Err(ProofError::VerificationFailure),
};
let mut total = 31;
// for level in 0..trust_level {
// let level_interval: u32 = LEVEL_INTERVAL[trust_level as usize];
// total += level_interval;
total += trust_level*85;
// }
Ok(total)
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
pub fn log(s: &str);
}
#[wasm_bindgen]
pub fn set_panic_hook() {
panic::set_hook(Box::new(console_error_panic_hook::hook));
}
#[wasm_bindgen]
pub fn open_invite(invite: &[u8]) -> Result<String, JsValue> {
unsafe {
log(&format!("Using invite: {:?}", invite));
}
let token = match validate(invite) {
Ok(token) => token,
Err(e) => return Err(JsValue::from(e.to_string())),
};
let (request, state) = open_invite::request(&token);
let req_state = OpenReqState {
request,
state,
};
unsafe {
log(&format!(
"Formatted open invite request: {}",
serde_json::to_string(&req_state).unwrap()
));
}
Ok(serde_json::to_string(&req_state).unwrap())
}
#[wasm_bindgen]
pub fn handle_new_lox_credential(
open_lox_result: String,
open_lox_response: String,
lox_pub: String,
) -> Result<String, JsValue> {
let req_state: OpenReqState = serde_json::from_str(&open_lox_result).unwrap();
let deserialized_state = req_state.state;
let deserialized_response = serde_json::from_str(&open_lox_response).unwrap();
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let lox_cred = match open_invite::handle_response(
deserialized_state,
deserialized_response,
&pubkeys.lox_pub,
) {
Ok(lox_cred) => lox_cred,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
let lox_cred = LoxCredential {
lox_credential: lox_cred.0,
bridgeline: Some(lox_cred.1),
invitation: None,
};
unsafe {
log(&format!(
"Got new Lox Credential: {}",
serde_json::to_string(&lox_cred.lox_credential).unwrap()
));
log(&format!(
"Got new bridgeline: {}",
serde_json::to_string(&lox_cred.bridgeline).unwrap()
));
}
Ok(serde_json::to_string(&lox_cred).unwrap())
}
#[wasm_bindgen]
pub fn trust_promotion(open_lox_cred: String, lox_pub: String) -> Result<String, JsValue> {
let lox_cred: LoxCredential = serde_json::from_str(&open_lox_cred).unwrap();
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
// To test creation of the credential we need to advance the day to 30
// in production this should just use the today() function
log(&format!(
"TEST ONLY: Add 31 days to today's date: {}",
test_today(31)
));
let tp_result =
//CHANGE add_today(31) to today() for production
match trust_promotion::request(&lox_cred.lox_credential, &pubkeys.lox_pub, test_today(31)) {
Ok(tp_result) => tp_result,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
let req_state = TrustReqState {
request: tp_result.0,
state: tp_result.1,
};
unsafe {
log(&format!(
"Formatted Trust Promotion request: {}",
serde_json::to_string(&req_state).unwrap()
));
}
Ok(serde_json::to_string(&req_state).unwrap())
}
#[wasm_bindgen]
pub fn handle_trust_promotion(
trust_promo_request: String,
trust_promo_response: String,
) -> Result<String, JsValue> {
let req_state: TrustReqState = serde_json::from_str(&trust_promo_request).unwrap();
let deserialized_state = req_state.state;
let deserialized_response = serde_json::from_str(&trust_promo_response).unwrap();
let migration_cred =
match trust_promotion::handle_response(deserialized_state, deserialized_response) {
Ok(migration_cred) => migration_cred,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
unsafe {
log(&format!(
"Got new Migration Credential: {}",
serde_json::to_string(&migration_cred).unwrap()
));
}
Ok(serde_json::to_string(&migration_cred).unwrap())
}
#[wasm_bindgen]
pub fn trust_migration(open_lox_cred: String, trust_promo_cred: String, lox_pub: String) -> Result<String, JsValue> {
let lox_cred: LoxCredential = serde_json::from_str(&open_lox_cred).unwrap();
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let mig_cred: Migration = serde_json::from_str(&trust_promo_cred).unwrap();
let tm_result =
match migration::request(&lox_cred.lox_credential, &mig_cred, &pubkeys.lox_pub, &pubkeys.migration_pub) {
Ok(tm_result) => tm_result,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
let req_state = MigReqState {
request: tm_result.0,
state: tm_result.1,
};
unsafe {
log(&format!(
"Formatted Trust Migration request: {}",
serde_json::to_string(&req_state).unwrap()
));
}
Ok(serde_json::to_string(&req_state).unwrap())
}
#[wasm_bindgen]
pub fn handle_trust_migration(
trust_migration_request: String,
trust_migration_response: String,
lox_pub: String
) -> Result<String, JsValue> {
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let req_state: MigReqState = serde_json::from_str(&trust_migration_request).unwrap();
let deserialized_state = req_state.state;
let deserialized_response = serde_json::from_str(&trust_migration_response).unwrap();
let level_one_cred =
match migration::handle_response(deserialized_state, deserialized_response, &pubkeys.lox_pub) {
Ok(level_1_cred) => LoxCredential {
lox_credential: level_1_cred,
bridgeline: None,
invitation: None,
},
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
unsafe {
log(&format!(
"Got new Level 1 Credential: {}",
serde_json::to_string(&level_one_cred).unwrap()
));
}
Ok(serde_json::to_string(&level_one_cred).unwrap())
}
fn generate_reachability_cred(lox_cred: &Lox, encrypted_table: String) -> BucketReachability {
let (id, key) = from_scalar(lox_cred.bucket).unwrap();
let enc_buckets: EncBridgeTable = serde_json::from_str(&encrypted_table).unwrap();
let bucket = BridgeTable::decrypt_bucket(id, &key, &enc_buckets.etable[id as usize]).unwrap();
bucket.1.unwrap()
}
#[wasm_bindgen]
pub fn level_up(level_one_cred: String, encrypted_table: String, lox_pub: String) -> Result<String, JsValue> {
let lox_cred: LoxCredential = serde_json::from_str(&level_one_cred).unwrap();
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let reach_cred = generate_reachability_cred(&lox_cred.lox_credential, encrypted_table);
// To test level up of the credential we need to advance the day to the correct interval
// In this case, the maximum of 85 can be used to test all level ups
// in production this should just use the today() function
// decrypt trust level and use to calculate the correct date for now
// The trust level has to be at least 1
let test_cumulative_days = match calc_test_days(&lox_cred.lox_credential) {
Ok(v) => v,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
log(&format!(
"TEST ONLY: Add 31 (open invitation) + Trust Level*85 days to today's date: {}", test_today(test_cumulative_days)
));
let lu_result =
//CHANGE add_today(31) to today() for production
match level_up::request(&lox_cred.lox_credential, &reach_cred, &pubkeys.lox_pub, &pubkeys.reachability_pub, test_today(test_cumulative_days)) {
Ok(lu_result) => lu_result,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
let req_state = LevelupReqState {
request: lu_result.0,
state: lu_result.1,
};
unsafe {
log(&format!(
"Formatted Level Up request: {}",
serde_json::to_string(&req_state).unwrap()
));
}
Ok(serde_json::to_string(&req_state).unwrap())
}
#[wasm_bindgen]
pub fn handle_level_up(
levelup_request: String,
levelup_response: String,
lox_pub: String
) -> Result<String, JsValue> {
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let req_state: LevelupReqState = serde_json::from_str(&levelup_request).unwrap();
let deserialized_state = req_state.state;
let deserialized_response = serde_json::from_str(&levelup_response).unwrap();
let level_up_cred =
match level_up::handle_response(deserialized_state, deserialized_response, &pubkeys.lox_pub) {
Ok(level_up_cred) => LoxCredential {
lox_credential: level_up_cred,
bridgeline: None,
invitation: None,
},
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
unsafe {
log(&format!(
"Got new Level Up Credential: {}",
serde_json::to_string(&level_up_cred).unwrap()
));
}
Ok(serde_json::to_string(&level_up_cred).unwrap())
}
#[wasm_bindgen]
pub fn issue_invite(trusted_cred: String, encrypted_table: String, lox_pub: String) -> Result<String, JsValue> {
let lox_cred: LoxCredential = serde_json::from_str(&trusted_cred).unwrap();
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let reach_cred = generate_reachability_cred(&lox_cred.lox_credential, encrypted_table);
let issue_result =
match issue_invite::request(&lox_cred.lox_credential, &reach_cred, &pubkeys.lox_pub, &pubkeys.reachability_pub, test_today(371)) {
Ok(issue_result) => issue_result,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
let req_state = IssueInviteReqState {
request: issue_result.0,
state: issue_result.1,
};
unsafe {
log(&format!(
"Formatted Issue Invite request: {}",
serde_json::to_string(&req_state).unwrap()
));
}
Ok(serde_json::to_string(&req_state).unwrap())
}
#[wasm_bindgen]
pub fn handle_issue_invite(
issue_invite_request: String,
issue_invite_response: String,
lox_pub: String
) -> Result<String, JsValue> {
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let req_state: IssueInviteReqState = serde_json::from_str(&issue_invite_request).unwrap();
let deserialized_state = req_state.state;
let deserialized_response = serde_json::from_str(&issue_invite_response).unwrap();
let issue_invite_cred =
match issue_invite::handle_response(deserialized_state, deserialized_response, &pubkeys.lox_pub, &pubkeys.invitation_pub) {
Ok(issue_invite_cred) => issue_invite_cred,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
let invitation_cred = LoxCredential {
lox_credential: issue_invite_cred.0,
bridgeline: None,
invitation: Some(issue_invite_cred.1),
};
unsafe {
log(&format!(
"Got new Invitation Credential and Lox Credential: {}",
serde_json::to_string(&invitation_cred).unwrap()
));
}
Ok(serde_json::to_string(&invitation_cred).unwrap())
}
// Separate Trusted Invite from credential prior to passing it to friend
#[wasm_bindgen]
pub fn prepare_invite(invitation_cred: String) -> String {
let cred: LoxCredential = serde_json::from_str(&invitation_cred).unwrap();
log(&format!(
"Prepared Invitation: {}",
serde_json::to_string(&cred.invitation).unwrap()
));
serde_json::to_string(&cred.invitation).unwrap()
}
//
#[wasm_bindgen]
pub fn redeem_invite(invitation: String, lox_pub: String) -> Result<String, JsValue> {
let invitation_cred: Invitation = serde_json::from_str(&invitation).unwrap();
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let redeem_result =
match redeem_invite::request(&invitation_cred, &pubkeys.invitation_pub, test_today(371)) {
Ok(redeem_result) => redeem_result,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
let req_state = RedeemReqState {
request: redeem_result.0,
state: redeem_result.1,
};
unsafe {
log(&format!(
"Formatted Redeem Invite request: {}",
serde_json::to_string(&req_state).unwrap()
));
}
Ok(serde_json::to_string(&req_state).unwrap())
}
#[wasm_bindgen]
pub fn handle_redeem_invite(
redeem_invite_request: String,
redeem_invite_response: String,
lox_pub: String
) -> Result<String, JsValue> {
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let req_state: RedeemReqState = serde_json::from_str(&redeem_invite_request).unwrap();
let deserialized_state = req_state.state;
let deserialized_response = serde_json::from_str(&redeem_invite_response).unwrap();
let redeem_invite_cred =
match redeem_invite::handle_response(deserialized_state, deserialized_response, &pubkeys.lox_pub) {
Ok(issue_invite_cred) => LoxCredential {
lox_credential: issue_invite_cred,
bridgeline: None,
invitation: None,
},
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
unsafe {
log(&format!(
"Got new Trusted Lox Credential from Invitation: {}",
serde_json::to_string(&redeem_invite_cred).unwrap()
));
}
Ok(serde_json::to_string(&redeem_invite_cred).unwrap())
}
#[wasm_bindgen]
pub fn check_blockage(lox_cred: String, lox_pub: String) -> Result<String, JsValue> {
let lox: LoxCredential = serde_json::from_str(&lox_cred).unwrap();
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let cb_result =
match check_blockage::request(&lox.lox_credential, &pubkeys.lox_pub) {
Ok(cb_result) => cb_result,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
let req_state = CheckBlockageReqState {
request: cb_result.0,
state: cb_result.1,
};
unsafe {
log(&format!(
"Formatted Check Blockage request: {}",
serde_json::to_string(&req_state).unwrap()
));
}
Ok(serde_json::to_string(&req_state).unwrap())
}
#[wasm_bindgen]
pub fn handle_check_blockage(
check_blockage_request: String,
check_blockage_response: String,
) -> Result<String, JsValue> {
let req_state: CheckBlockageReqState = serde_json::from_str(&check_blockage_request).unwrap();
let deserialized_state = req_state.state;
let deserialized_response = serde_json::from_str(&check_blockage_response).unwrap();
let migration_cred =
match check_blockage::handle_response(deserialized_state, deserialized_response) {
Ok(migration_cred) => migration_cred,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
unsafe {
log(&format!(
"Got new Blockage Migration Credential: {}",
serde_json::to_string(&migration_cred).unwrap()
));
}
Ok(serde_json::to_string(&migration_cred).unwrap())
}
#[wasm_bindgen]
pub fn blockage_migration(lox_cred: String, check_migration_cred: String, lox_pub: String) -> Result<String, JsValue> {
let lox_cred: LoxCredential = serde_json::from_str(&lox_cred).unwrap();
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let mig_cred: Migration = serde_json::from_str(&check_migration_cred).unwrap();
let bm_result =
match blockage_migration::request(&lox_cred.lox_credential, &mig_cred, &pubkeys.lox_pub, &pubkeys.migration_pub) {
Ok(bm_result) => bm_result,
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
let req_state = BlockageMigReqState {
request: bm_result.0,
state: bm_result.1,
};
unsafe {
log(&format!(
"Formatted Blockage Migration request: {}",
serde_json::to_string(&req_state).unwrap()
));
}
Ok(serde_json::to_string(&req_state).unwrap())
}
#[wasm_bindgen]
pub fn handle_blockage_migration(
blockage_migration_request: String,
blockage_migration_response: String,
lox_pub: String
) -> Result<String, JsValue> {
let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap();
let req_state: BlockageMigReqState = serde_json::from_str(&blockage_migration_request).unwrap();
let deserialized_state = req_state.state;
let deserialized_response = serde_json::from_str(&blockage_migration_response).unwrap();
let lox_cred =
match blockage_migration::handle_response(deserialized_state, deserialized_response, &pubkeys.lox_pub) {
Ok(lox_cred) => LoxCredential {
lox_credential: lox_cred,
bridgeline: None,
invitation: None,
},
Err(e) => {
log(&format!("Error: {:?}", e.to_string()));
return Err(JsValue::from(e.to_string()));
}
};
unsafe {
log(&format!(
"Got new Lox Credential after Migration: {}",
serde_json::to_string(&lox_cred).unwrap()
));
}
Ok(serde_json::to_string(&lox_cred).unwrap())
}
// This should also check the pubkey
fn validate(invite: &[u8]) -> Result<[u8; OPENINV_LENGTH], TryFromSliceError> {
invite.try_into()
}