Mock attestation (#82)
Co-authored-by: Ethan Buchman <ethan@coinculture.info>
This commit is contained in:
parent
fe06f244ad
commit
4b3630adf3
33 changed files with 228 additions and 4299 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2379,6 +2379,7 @@ dependencies = [
|
||||||
"quartz-proto",
|
"quartz-proto",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"sha2 0.10.8",
|
||||||
"tendermint 0.36.0",
|
"tendermint 0.36.0",
|
||||||
"tendermint-light-client",
|
"tendermint-light-client",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
|
|
@ -19,6 +19,9 @@ panic = 'abort'
|
||||||
incremental = false
|
incremental = false
|
||||||
overflow-checks = true
|
overflow-checks = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
mock-sgx = ["quartz-cw/mock-sgx"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# external
|
# external
|
||||||
hex = { version = "0.4.3", default-features = false }
|
hex = { version = "0.4.3", default-features = false }
|
||||||
|
|
|
@ -3,26 +3,26 @@ use std::collections::BTreeMap;
|
||||||
use cosmwasm_schema::{cw_serde, QueryResponses};
|
use cosmwasm_schema::{cw_serde, QueryResponses};
|
||||||
use cosmwasm_std::{HexBinary, Uint64};
|
use cosmwasm_std::{HexBinary, Uint64};
|
||||||
use quartz_cw::{
|
use quartz_cw::{
|
||||||
msg::execute::attested::{RawAttested, RawAttestedMsgSansHandler, RawEpidAttestation},
|
msg::execute::attested::{RawAttested, RawAttestedMsgSansHandler, RawDefaultAttestation},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::state::{RawHash, SettleOff};
|
use crate::state::{RawHash, SettleOff};
|
||||||
|
|
||||||
type AttestedMsg<M> = RawAttested<RawAttestedMsgSansHandler<M>, RawEpidAttestation>;
|
type AttestedMsg<M, RA> = RawAttested<RawAttestedMsgSansHandler<M>, RA>;
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct InstantiateMsg(pub QuartzInstantiateMsg);
|
pub struct InstantiateMsg<RA = RawDefaultAttestation>(pub QuartzInstantiateMsg<RA>);
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum ExecuteMsg {
|
pub enum ExecuteMsg<RA = RawDefaultAttestation> {
|
||||||
Quartz(QuartzExecuteMsg),
|
Quartz(QuartzExecuteMsg),
|
||||||
FaucetMint(execute::FaucetMintMsg),
|
FaucetMint(execute::FaucetMintMsg),
|
||||||
Transfer(execute::Cw20Transfer),
|
Transfer(execute::Cw20Transfer),
|
||||||
SubmitObligation(execute::SubmitObligationMsg),
|
SubmitObligation(execute::SubmitObligationMsg),
|
||||||
SubmitObligations(execute::SubmitObligationsMsg),
|
SubmitObligations(execute::SubmitObligationsMsg),
|
||||||
SubmitSetoffs(AttestedMsg<execute::SubmitSetoffsMsg>),
|
SubmitSetoffs(AttestedMsg<execute::SubmitSetoffsMsg, RA>),
|
||||||
InitClearing,
|
InitClearing,
|
||||||
SetLiquiditySources(execute::SetLiquiditySourcesMsg),
|
SetLiquiditySources(execute::SetLiquiditySourcesMsg),
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,9 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Informal Systems <hello@informal.systems>"]
|
authors = ["Informal Systems <hello@informal.systems>"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
mock-sgx = ["quartz-cw/mock-sgx", "quartz-enclave/mock-sgx"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# external
|
# external
|
||||||
clap.workspace = true
|
clap.workspace = true
|
||||||
|
|
|
@ -28,7 +28,7 @@ use mtcs_server::MtcsService;
|
||||||
use proto::clearing_server::ClearingServer as MtcsServer;
|
use proto::clearing_server::ClearingServer as MtcsServer;
|
||||||
use quartz_cw::state::{Config, LightClientOpts};
|
use quartz_cw::state::{Config, LightClientOpts};
|
||||||
use quartz_enclave::{
|
use quartz_enclave::{
|
||||||
attestor::{Attestor, EpidAttestor},
|
attestor::{Attestor, DefaultAttestor},
|
||||||
server::CoreService,
|
server::CoreService,
|
||||||
};
|
};
|
||||||
use quartz_proto::quartz::core_server::CoreServer;
|
use quartz_proto::quartz::core_server::CoreServer;
|
||||||
|
@ -53,8 +53,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
args.max_block_lag,
|
args.max_block_lag,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let attestor = DefaultAttestor::default();
|
||||||
|
|
||||||
let config = Config::new(
|
let config = Config::new(
|
||||||
EpidAttestor.mr_enclave()?,
|
attestor.mr_enclave()?,
|
||||||
Duration::from_secs(30 * 24 * 60),
|
Duration::from_secs(30 * 24 * 60),
|
||||||
light_client_opts,
|
light_client_opts,
|
||||||
);
|
);
|
||||||
|
@ -65,9 +67,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.add_service(CoreServer::new(CoreService::new(
|
.add_service(CoreServer::new(CoreService::new(
|
||||||
config,
|
config,
|
||||||
sk.clone(),
|
sk.clone(),
|
||||||
EpidAttestor,
|
attestor.clone(),
|
||||||
)))
|
)))
|
||||||
.add_service(MtcsServer::new(MtcsService::new(sk.clone(), EpidAttestor)))
|
.add_service(MtcsServer::new(MtcsService::new(sk, attestor)))
|
||||||
.serve(args.rpc_addr)
|
.serve(args.rpc_addr)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ You may want to exit and start a new terminal session to get the rust toolchain
|
||||||
Now downgrade rust to v1.76.0:
|
Now downgrade rust to v1.76.0:
|
||||||
|
|
||||||
```
|
```
|
||||||
rustup install v1.76.0
|
rustup install 1.76.0
|
||||||
rustup default v1.76.0
|
rustup default 1.76.0
|
||||||
```
|
```
|
||||||
|
|
||||||
Check the version with `cargo version`.
|
Check the version with `cargo version`.
|
||||||
|
@ -61,7 +61,7 @@ git checkout v0.44.0
|
||||||
go install ./cmd/wasmd
|
go install ./cmd/wasmd
|
||||||
```
|
```
|
||||||
|
|
||||||
Check that both work by running `grpccurl` and `wasmd`.
|
Check that both work by running `grpcurl` and `wasmd`.
|
||||||
|
|
||||||
Finally, you neeed `websocat`:
|
Finally, you neeed `websocat`:
|
||||||
|
|
||||||
|
@ -114,6 +114,19 @@ First set the `NODE_URL` variable to the address of the blockchain node. If it's
|
||||||
The `scripts` dir contains some bash scripts to help run the app.
|
The `scripts` dir contains some bash scripts to help run the app.
|
||||||
These scripts should be replaced by a new `quartz` tool. See [issue](https://github.com/informalsystems/cycles-quartz/issues/61).
|
These scripts should be replaced by a new `quartz` tool. See [issue](https://github.com/informalsystems/cycles-quartz/issues/61).
|
||||||
|
|
||||||
|
Note: to build/run on a non-SGX machine you must set the `MOCK_SGX` env var for all bash scripts below
|
||||||
|
```
|
||||||
|
# 1st Terminal
|
||||||
|
$ export MOCK_SGX=1
|
||||||
|
$ bash scripts/build.sh
|
||||||
|
$ bash scripts/start.sh
|
||||||
|
|
||||||
|
# 2nd Terminal
|
||||||
|
$ export MOCK_SGX=1
|
||||||
|
$ bash scripts/deploy.sh
|
||||||
|
$ ...
|
||||||
|
```
|
||||||
|
|
||||||
### Build the Binaries
|
### Build the Binaries
|
||||||
|
|
||||||
Build the enclave binary and the smart contract binary:
|
Build the enclave binary and the smart contract binary:
|
||||||
|
|
|
@ -23,6 +23,9 @@ panic = 'abort'
|
||||||
incremental = false
|
incremental = false
|
||||||
overflow-checks = true
|
overflow-checks = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
mock-sgx = ["quartz-cw/mock-sgx"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# external
|
# external
|
||||||
sha2 = "0.10.8"
|
sha2 = "0.10.8"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use cosmwasm_schema::write_api;
|
use cosmwasm_schema::write_api;
|
||||||
use transfers_contracts::msg::{ExecuteMsg, InstantiateMsg};
|
use transfers_contract::msg::{ExecuteMsg, InstantiateMsg};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
write_api! {
|
write_api! {
|
||||||
|
|
|
@ -1 +1,8 @@
|
||||||
RUSTFLAGS='-C link-arg=-s' cargo wasm
|
FEATURES=
|
||||||
|
|
||||||
|
if [ -n "$MOCK_SGX" ]; then
|
||||||
|
echo "MOCK_SGX is set. Adding mock-sgx feature."
|
||||||
|
FEATURES="--features=mock-sgx"
|
||||||
|
fi
|
||||||
|
|
||||||
|
RUSTFLAGS='-C link-arg=-s' cargo wasm $FEATURES
|
||||||
|
|
|
@ -60,7 +60,7 @@ TX_HASH=$(echo $RES | jq -r '.["txhash"]')
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
while ! $CMD query tx $TX_HASH &> /dev/null; do
|
while ! $CMD query tx $TX_HASH &> /dev/null; do
|
||||||
echo "... 🕐 waiting for contract to be queryable"
|
echo "... 🕐 waiting for contract to be queryable from tx hash $TX_HASH"
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
use cosmwasm_schema::cw_serde;
|
use cosmwasm_schema::cw_serde;
|
||||||
use cosmwasm_std::{Addr, HexBinary, Uint128};
|
use cosmwasm_std::{Addr, HexBinary, Uint128};
|
||||||
use quartz_cw::{
|
use quartz_cw::{
|
||||||
msg::execute::attested::{RawAttested, RawEpidAttestation},
|
msg::execute::attested::{RawAttested, RawDefaultAttestation},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct InstantiateMsg {
|
pub struct InstantiateMsg<RA = RawDefaultAttestation> {
|
||||||
pub quartz: QuartzInstantiateMsg,
|
pub quartz: QuartzInstantiateMsg<RA>,
|
||||||
pub denom: String,
|
pub denom: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum ExecuteMsg {
|
pub enum ExecuteMsg<RA = RawDefaultAttestation> {
|
||||||
// quartz initialization
|
// quartz initialization
|
||||||
Quartz(QuartzExecuteMsg),
|
Quartz(QuartzExecuteMsg),
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ pub enum ExecuteMsg {
|
||||||
ClearTextTransferRequest(execute::ClearTextTransferRequestMsg),
|
ClearTextTransferRequest(execute::ClearTextTransferRequestMsg),
|
||||||
|
|
||||||
// enclave msg
|
// enclave msg
|
||||||
Update(RawAttested<execute::RawUpdateMsg, RawEpidAttestation>),
|
Update(RawAttested<execute::RawUpdateMsg, RA>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod execute {
|
pub mod execute {
|
||||||
|
|
4186
apps/transfers/enclave/Cargo.lock
generated
4186
apps/transfers/enclave/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -3,12 +3,15 @@ name = "quartz-app-transfers-enclave"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Informal Systems <hello@informal.systems>"]
|
authors = ["Informal Systems <hello@informal.systems>"]
|
||||||
autobins = false
|
default-run = "quartz-app-transfers-enclave"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "encrypt"
|
name = "encrypt"
|
||||||
path = "bin/encrypt.rs"
|
path = "bin/encrypt.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
mock-sgx = ["quartz-cw/mock-sgx", "quartz-enclave/mock-sgx"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# external
|
# external
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
|
@ -20,6 +23,7 @@ k256.workspace = true
|
||||||
prost.workspace = true
|
prost.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
sha2.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
tonic.workspace = true
|
tonic.workspace = true
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use anyhow;
|
use anyhow;
|
||||||
use cosmwasm_std::{Addr, HexBinary, Uint128};
|
use cosmwasm_std::{Addr, HexBinary, Uint128};
|
||||||
use ecies::{decrypt, encrypt};
|
use ecies::encrypt;
|
||||||
use k256::{
|
use k256::ecdsa::VerifyingKey;
|
||||||
ecdsa::{SigningKey, VerifyingKey},
|
|
||||||
pkcs8::DecodePublicKey,
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use transfers_contract::msg::execute::ClearTextTransferRequestMsg;
|
use transfers_contract::msg::execute::ClearTextTransferRequestMsg;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Quartz manifest file
|
# Quartz manifest file
|
||||||
|
|
||||||
loader.entrypoint = "file:{{ gramine.libos }}"
|
loader.entrypoint = "file:{{ gramine.libos }}"
|
||||||
libos.entrypoint = "{{ quartz_dir }}/target/release/enclave"
|
libos.entrypoint = "{{ quartz_dir }}/target/release/quartz-app-transfers-enclave"
|
||||||
|
|
||||||
loader.log_level = "{{ log_level }}"
|
loader.log_level = "{{ log_level }}"
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ loader.env.RA_TLS_EPID_API_KEY = { passthrough = true }
|
||||||
loader.env.MYAPP_DATA = { passthrough = true }
|
loader.env.MYAPP_DATA = { passthrough = true }
|
||||||
loader.env.QUARTZ_PORT = { passthrough = true }
|
loader.env.QUARTZ_PORT = { passthrough = true }
|
||||||
|
|
||||||
loader.argv = ["enclave",
|
loader.argv = ["quartz-app-transfers-enclave",
|
||||||
"--chain-id", "testing",
|
"--chain-id", "testing",
|
||||||
"--trusted-height", "{{ trusted_height }}",
|
"--trusted-height", "{{ trusted_height }}",
|
||||||
"--trusted-hash", "{{ trusted_hash }}"]
|
"--trusted-hash", "{{ trusted_hash }}"]
|
||||||
|
@ -43,7 +43,7 @@ sgx.ra_client_linkable = {{ 'true' if ra_client_linkable == '1' else 'false' }}
|
||||||
|
|
||||||
sgx.trusted_files = [
|
sgx.trusted_files = [
|
||||||
"file:{{ gramine.libos }}",
|
"file:{{ gramine.libos }}",
|
||||||
"file:{{ quartz_dir }}/target/release/enclave",
|
"file:{{ quartz_dir }}/target/release/quartz-app-transfers-enclave",
|
||||||
"file:{{ gramine.runtimedir() }}/",
|
"file:{{ gramine.runtimedir() }}/",
|
||||||
"file:{{ arch_libdir }}/",
|
"file:{{ arch_libdir }}/",
|
||||||
"file:/usr/{{ arch_libdir }}/",
|
"file:/usr/{{ arch_libdir }}/",
|
||||||
|
|
|
@ -51,8 +51,9 @@ pub struct Cli {
|
||||||
pub max_block_lag: u64,
|
pub max_block_lag: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn default_rpc_addr() -> SocketAddr {
|
fn default_rpc_addr() -> SocketAddr {
|
||||||
let port = env::var("QUARTZ_PORT").unwrap_or_else(|_| "11090".to_string());
|
let port = env::var("QUARTZ_PORT").unwrap_or_else(|_| "11090".to_string());
|
||||||
format!("127.0.0.1:{}", port).parse().expect("Invalid socket address")
|
format!("127.0.0.1:{}", port)
|
||||||
|
.parse()
|
||||||
|
.expect("Invalid socket address")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
clippy::checked_conversions,
|
clippy::checked_conversions,
|
||||||
clippy::panic,
|
clippy::panic,
|
||||||
clippy::panic_in_result_fn,
|
clippy::panic_in_result_fn,
|
||||||
missing_docs,
|
|
||||||
trivial_casts,
|
trivial_casts,
|
||||||
trivial_numeric_casts,
|
trivial_numeric_casts,
|
||||||
rust_2018_idioms,
|
rust_2018_idioms,
|
||||||
|
@ -28,7 +27,7 @@ use cli::Cli;
|
||||||
use proto::settlement_server::SettlementServer as TransfersServer;
|
use proto::settlement_server::SettlementServer as TransfersServer;
|
||||||
use quartz_cw::state::{Config, LightClientOpts};
|
use quartz_cw::state::{Config, LightClientOpts};
|
||||||
use quartz_enclave::{
|
use quartz_enclave::{
|
||||||
attestor::{Attestor, EpidAttestor},
|
attestor::{Attestor, DefaultAttestor},
|
||||||
server::CoreService,
|
server::CoreService,
|
||||||
};
|
};
|
||||||
use quartz_proto::quartz::core_server::CoreServer;
|
use quartz_proto::quartz::core_server::CoreServer;
|
||||||
|
@ -54,8 +53,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
args.max_block_lag,
|
args.max_block_lag,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let attestor = DefaultAttestor::default();
|
||||||
|
|
||||||
let config = Config::new(
|
let config = Config::new(
|
||||||
EpidAttestor.mr_enclave()?,
|
attestor.mr_enclave()?,
|
||||||
Duration::from_secs(30 * 24 * 60),
|
Duration::from_secs(30 * 24 * 60),
|
||||||
light_client_opts,
|
light_client_opts,
|
||||||
);
|
);
|
||||||
|
@ -66,12 +67,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.add_service(CoreServer::new(CoreService::new(
|
.add_service(CoreServer::new(CoreService::new(
|
||||||
config,
|
config,
|
||||||
sk.clone(),
|
sk.clone(),
|
||||||
EpidAttestor,
|
attestor.clone(),
|
||||||
)))
|
|
||||||
.add_service(TransfersServer::new(TransfersService::<EpidAttestor>::new(
|
|
||||||
sk.clone(),
|
|
||||||
EpidAttestor,
|
|
||||||
)))
|
)))
|
||||||
|
.add_service(TransfersServer::new(TransfersService::new(sk, attestor)))
|
||||||
.serve(args.rpc_addr)
|
.serve(args.rpc_addr)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use anyhow;
|
use anyhow;
|
||||||
use cosmwasm_std::{Addr, HexBinary, Uint128};
|
use cosmwasm_std::{Addr, HexBinary, Uint128};
|
||||||
|
|
|
@ -4,9 +4,6 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use cosmwasm_std::{Addr, HexBinary, Uint128};
|
use cosmwasm_std::{Addr, HexBinary, Uint128};
|
||||||
|
|
||||||
pub type RawCipherText = HexBinary;
|
|
||||||
|
|
||||||
use ecies::{decrypt, encrypt};
|
use ecies::{decrypt, encrypt};
|
||||||
use k256::ecdsa::{SigningKey, VerifyingKey};
|
use k256::ecdsa::{SigningKey, VerifyingKey};
|
||||||
use quartz_cw::{
|
use quartz_cw::{
|
||||||
|
@ -17,13 +14,15 @@ use quartz_enclave::attestor::Attestor;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use tonic::{Request, Response, Result as TonicResult, Status};
|
use tonic::{Request, Response, Result as TonicResult, Status};
|
||||||
use transfers_contracts::msg::execute::{ClearTextTransferRequestMsg, Request as TransfersRequest};
|
use transfers_contract::msg::execute::{ClearTextTransferRequestMsg, Request as TransfersRequest};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
proto::{settlement_server::Settlement, RunTransfersRequest, RunTransfersResponse},
|
proto::{settlement_server::Settlement, RunTransfersRequest, RunTransfersResponse},
|
||||||
state::{RawState, State},
|
state::{RawState, State},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub type RawCipherText = HexBinary;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TransfersService<A> {
|
pub struct TransfersService<A> {
|
||||||
sk: Arc<Mutex<Option<SigningKey>>>,
|
sk: Arc<Mutex<Option<SigningKey>>>,
|
||||||
|
@ -178,10 +177,11 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
// Attest to message
|
// Attest to message
|
||||||
let attestation = self
|
let attestation: HexBinary = self
|
||||||
.attestor
|
.attestor
|
||||||
.quote(msg.clone())
|
.quote(msg.clone())
|
||||||
.map_err(|e| Status::internal(e.to_string()))?;
|
.map_err(|e| Status::internal(e.to_string()))?
|
||||||
|
.into();
|
||||||
|
|
||||||
let attested_msg = RawAttested { msg, attestation };
|
let attested_msg = RawAttested { msg, attestation };
|
||||||
let message =
|
let message =
|
||||||
|
|
|
@ -3,16 +3,22 @@
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
ROOT=${ROOT:-$HOME}
|
ROOT=${ROOT:-$HOME}
|
||||||
|
FEATURES=
|
||||||
|
|
||||||
|
if [ -n "$MOCK_SGX" ]; then
|
||||||
|
echo "MOCK_SGX is set. Adding mock-sgx feature."
|
||||||
|
FEATURES="--features=mock-sgx"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "--------------------------------------------------------"
|
echo "--------------------------------------------------------"
|
||||||
echo "building enclave binary"
|
echo "building enclave binary"
|
||||||
|
|
||||||
cd $ROOT/cycles-quartz/apps/transfers/enclave
|
cd $ROOT/cycles-quartz/apps/transfers/enclave
|
||||||
CARGO_TARGET_DIR=./target cargo build --release
|
CARGO_TARGET_DIR=./target cargo build --release $FEATURES
|
||||||
|
|
||||||
echo "--------------------------------------------------------"
|
echo "--------------------------------------------------------"
|
||||||
echo "building cosmwasm contract binary"
|
echo "building cosmwasm contract binary"
|
||||||
|
|
||||||
|
|
||||||
cd $ROOT/cycles-quartz/apps/transfers/contracts
|
cd $ROOT/cycles-quartz/apps/transfers/contracts
|
||||||
bash build.sh
|
bash build.sh $FEATURES
|
||||||
|
|
|
@ -9,12 +9,13 @@ echo "--------------------------------------------------------"
|
||||||
echo "instantiate"
|
echo "instantiate"
|
||||||
cd $ROOT/cycles-quartz/relayer/
|
cd $ROOT/cycles-quartz/relayer/
|
||||||
export INSTANTIATE_MSG=$(./scripts/relay.sh Instantiate | jq '{quartz: .} + {denom: "ucosm"}' )
|
export INSTANTIATE_MSG=$(./scripts/relay.sh Instantiate | jq '{quartz: .} + {denom: "ucosm"}' )
|
||||||
|
echo $INSTANTIATE_MSG
|
||||||
echo "--------------------------------------------------------"
|
echo "--------------------------------------------------------"
|
||||||
|
|
||||||
echo "deploy contract"
|
echo "deploy contract"
|
||||||
cd $ROOT/cycles-quartz/apps/transfers/contracts/
|
cd $ROOT/cycles-quartz/apps/transfers/contracts/
|
||||||
|
|
||||||
bash deploy-contract.sh target/wasm32-unknown-unknown/release/transfers_contracts.wasm |& tee output
|
bash deploy-contract.sh target/wasm32-unknown-unknown/release/transfers_contract.wasm 2>&1 | tee output
|
||||||
export CONTRACT=$(cat output | grep Address | awk '{print $NF}' | sed 's/\x1b\[[0-9;]*m//g')
|
export CONTRACT=$(cat output | grep Address | awk '{print $NF}' | sed 's/\x1b\[[0-9;]*m//g')
|
||||||
echo $CONTRACT
|
echo $CONTRACT
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ cd $ROOT/cycles-quartz/relayer
|
||||||
|
|
||||||
# execute SessionCreate on enclave
|
# execute SessionCreate on enclave
|
||||||
export EXECUTE_CREATE=$(./scripts/relay.sh SessionCreate)
|
export EXECUTE_CREATE=$(./scripts/relay.sh SessionCreate)
|
||||||
|
echo $EXECUTE_CREATE
|
||||||
|
|
||||||
# submit SessionCreate to contract
|
# submit SessionCreate to contract
|
||||||
RES=$($CMD tx wasm execute "$CONTRACT" "$EXECUTE_CREATE" --from admin --chain-id testing -y --output json)
|
RES=$($CMD tx wasm execute "$CONTRACT" "$EXECUTE_CREATE" --from admin --chain-id testing -y --output json)
|
||||||
|
@ -43,14 +44,14 @@ TX_HASH=$(echo $RES | jq -r '.["txhash"]')
|
||||||
|
|
||||||
# wait for tx to commit
|
# wait for tx to commit
|
||||||
while ! $CMD query tx $TX_HASH &> /dev/null; do
|
while ! $CMD query tx $TX_HASH &> /dev/null; do
|
||||||
echo "... 🕐 waiting for tx"
|
echo "... 🕐 waiting for tx $TX_HASH"
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
# need to wait another block for light client proof
|
# need to wait another block for light client proof
|
||||||
BLOCK_HEIGHT=$($CMD query block | jq .block.header.height)
|
BLOCK_HEIGHT=$($CMD query block | jq .block.header.height)
|
||||||
|
|
||||||
echo "at heigh $BLOCK_HEIGHT. need to wait for a block"
|
echo "at height $BLOCK_HEIGHT. need to wait for a block"
|
||||||
while [[ $BLOCK_HEIGHT == $($CMD query block | jq .block.header.height) ]]; do
|
while [[ $BLOCK_HEIGHT == $($CMD query block | jq .block.header.height) ]]; do
|
||||||
echo "... 🕐 waiting for another block"
|
echo "... 🕐 waiting for another block"
|
||||||
sleep 1
|
sleep 1
|
||||||
|
@ -58,7 +59,7 @@ done
|
||||||
|
|
||||||
# need to wait another block for light client proof
|
# need to wait another block for light client proof
|
||||||
BLOCK_HEIGHT=$($CMD query block | jq .block.header.height)
|
BLOCK_HEIGHT=$($CMD query block | jq .block.header.height)
|
||||||
echo "at heigh $BLOCK_HEIGHT. need to wait for a block"
|
echo "at height $BLOCK_HEIGHT. need to wait for a block"
|
||||||
while [[ $BLOCK_HEIGHT == $($CMD query block | jq .block.header.height) ]]; do
|
while [[ $BLOCK_HEIGHT == $($CMD query block | jq .block.header.height) ]]; do
|
||||||
echo "... 🕐 waiting for another block"
|
echo "... 🕐 waiting for another block"
|
||||||
sleep 1
|
sleep 1
|
||||||
|
@ -78,12 +79,13 @@ fi
|
||||||
|
|
||||||
# TODO: pass this in?
|
# TODO: pass this in?
|
||||||
echo "trusted hash $TRUSTED_HASH"
|
echo "trusted hash $TRUSTED_HASH"
|
||||||
|
echo "trusted hash $TRUSTED_HEIGHT"
|
||||||
echo "contract $CONTRACT"
|
echo "contract $CONTRACT"
|
||||||
|
|
||||||
# run prover to get light client proof
|
# run prover to get light client proof
|
||||||
# TODO: assume this binary is pre-built?
|
# TODO: assume this binary is pre-built?
|
||||||
# TODO: pass in addresses and chain id
|
# TODO: pass in addresses and chain id
|
||||||
cargo run -vvv -- --chain-id testing \
|
cargo run -- --chain-id testing \
|
||||||
--primary "http://$NODE_URL" \
|
--primary "http://$NODE_URL" \
|
||||||
--witnesses "http://$NODE_URL" \
|
--witnesses "http://$NODE_URL" \
|
||||||
--trusted-height $TRUSTED_HEIGHT \
|
--trusted-height $TRUSTED_HEIGHT \
|
||||||
|
@ -104,7 +106,7 @@ TX_HASH=$(echo $RES | jq -r '.["txhash"]')
|
||||||
|
|
||||||
# wait for tx to commit
|
# wait for tx to commit
|
||||||
while ! $CMD query tx $TX_HASH &> /dev/null; do
|
while ! $CMD query tx $TX_HASH &> /dev/null; do
|
||||||
echo "... 🕐 waiting for tx"
|
echo "... 🕐 waiting for tx $TX_HASH"
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,14 @@ cd ""$DIR_QUARTZ_APP""
|
||||||
echo "$TRUSTED_HASH" > trusted.hash
|
echo "$TRUSTED_HASH" > trusted.hash
|
||||||
echo "$TRUSTED_HEIGHT" > trusted.height
|
echo "$TRUSTED_HEIGHT" > trusted.height
|
||||||
|
|
||||||
|
if [ -n "$MOCK_SGX" ]; then
|
||||||
|
echo "MOCK_SGX is set. Running enclave without gramine..."
|
||||||
|
cd $DIR_QUARTZ_ENCLAVE
|
||||||
|
./target/release/quartz-app-transfers-enclave --chain-id "testing" --trusted-height "$TRUSTED_HEIGHT" --trusted-hash "$TRUSTED_HASH"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo "--------------------------------------------------------"
|
echo "--------------------------------------------------------"
|
||||||
echo "configure gramine"
|
echo "configure gramine"
|
||||||
cd "$DIR_QUARTZ_ENCLAVE"
|
cd "$DIR_QUARTZ_ENCLAVE"
|
||||||
|
|
|
@ -9,8 +9,8 @@ repository.workspace = true
|
||||||
keywords = ["blockchain", "cosmos", "tendermint", "cycles", "quartz"]
|
keywords = ["blockchain", "cosmos", "tendermint", "cycles", "quartz"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[lib]
|
[features]
|
||||||
path = "src/lib.rs"
|
mock-sgx = ["quartz-cw/mock-sgx"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# external
|
# external
|
||||||
|
|
|
@ -8,6 +8,12 @@ use quartz_cw::{
|
||||||
state::{MrEnclave, UserData},
|
state::{MrEnclave, UserData},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock-sgx"))]
|
||||||
|
pub type DefaultAttestor = EpidAttestor;
|
||||||
|
|
||||||
|
#[cfg(feature = "mock-sgx")]
|
||||||
|
pub type DefaultAttestor = MockAttestor;
|
||||||
|
|
||||||
pub trait Attestor {
|
pub trait Attestor {
|
||||||
type Error: ToString;
|
type Error: ToString;
|
||||||
|
|
||||||
|
@ -16,7 +22,7 @@ pub trait Attestor {
|
||||||
fn mr_enclave(&self) -> Result<MrEnclave, Self::Error>;
|
fn mr_enclave(&self) -> Result<MrEnclave, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug, Default)]
|
||||||
pub struct EpidAttestor;
|
pub struct EpidAttestor;
|
||||||
|
|
||||||
impl Attestor for EpidAttestor {
|
impl Attestor for EpidAttestor {
|
||||||
|
@ -38,18 +44,19 @@ impl Attestor for EpidAttestor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug, Default)]
|
||||||
pub struct MockAttestor;
|
pub struct MockAttestor;
|
||||||
|
|
||||||
impl Attestor for MockAttestor {
|
impl Attestor for MockAttestor {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
|
|
||||||
fn quote(&self, _user_data: impl HasUserData) -> Result<Vec<u8>, Self::Error> {
|
fn quote(&self, user_data: impl HasUserData) -> Result<Vec<u8>, Self::Error> {
|
||||||
Ok(vec![])
|
let user_data = user_data.user_data();
|
||||||
|
Ok(user_data.to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mr_enclave(&self) -> Result<MrEnclave, Self::Error> {
|
fn mr_enclave(&self) -> Result<MrEnclave, Self::Error> {
|
||||||
Ok([0u8; 32])
|
Ok(Default::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
clippy::checked_conversions,
|
clippy::checked_conversions,
|
||||||
clippy::panic,
|
clippy::panic,
|
||||||
clippy::panic_in_result_fn,
|
clippy::panic_in_result_fn,
|
||||||
missing_docs,
|
|
||||||
trivial_casts,
|
trivial_casts,
|
||||||
trivial_numeric_casts,
|
trivial_numeric_casts,
|
||||||
rust_2018_idioms,
|
rust_2018_idioms,
|
||||||
|
|
|
@ -9,6 +9,9 @@ repository.workspace = true
|
||||||
keywords = ["blockchain", "cosmos", "cosmwasm", "cycles", "quartz"]
|
keywords = ["blockchain", "cosmos", "cosmwasm", "cycles", "quartz"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
mock-sgx = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# external
|
# external
|
||||||
k256.workspace = true
|
k256.workspace = true
|
||||||
|
|
|
@ -7,7 +7,7 @@ use cosmwasm_std::StdError;
|
||||||
|
|
||||||
use crate::msg::{
|
use crate::msg::{
|
||||||
execute::{
|
execute::{
|
||||||
attested::{Attested, EpidAttestation, RawAttested, RawEpidAttestation},
|
attested::{Attested, DefaultAttestation, RawAttested, RawDefaultAttestation},
|
||||||
session_create::{RawSessionCreate, SessionCreate},
|
session_create::{RawSessionCreate, SessionCreate},
|
||||||
session_set_pub_key::{RawSessionSetPubKey, SessionSetPubKey},
|
session_set_pub_key::{RawSessionSetPubKey, SessionSetPubKey},
|
||||||
},
|
},
|
||||||
|
@ -15,13 +15,13 @@ use crate::msg::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Execute<Attestation = EpidAttestation> {
|
pub enum Execute<Attestation = DefaultAttestation> {
|
||||||
SessionCreate(Attested<SessionCreate, Attestation>),
|
SessionCreate(Attested<SessionCreate, Attestation>),
|
||||||
SessionSetPubKey(Attested<SessionSetPubKey, Attestation>),
|
SessionSetPubKey(Attested<SessionSetPubKey, Attestation>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub enum RawExecute<RawAttestation = RawEpidAttestation> {
|
pub enum RawExecute<RawAttestation = RawDefaultAttestation> {
|
||||||
#[serde(rename = "session_create")]
|
#[serde(rename = "session_create")]
|
||||||
RawSessionCreate(RawAttested<RawSessionCreate, RawAttestation>),
|
RawSessionCreate(RawAttested<RawSessionCreate, RawAttestation>),
|
||||||
#[serde(rename = "session_set_pub_key")]
|
#[serde(rename = "session_set_pub_key")]
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
|
use std::{convert::Into, default::Default};
|
||||||
|
|
||||||
use cosmwasm_schema::cw_serde;
|
use cosmwasm_schema::cw_serde;
|
||||||
use cosmwasm_std::StdError;
|
use cosmwasm_std::{HexBinary, StdError};
|
||||||
use quartz_tee_ra::IASReport;
|
use quartz_tee_ra::IASReport;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock-sgx"))]
|
||||||
|
pub type DefaultAttestation = EpidAttestation;
|
||||||
|
#[cfg(not(feature = "mock-sgx"))]
|
||||||
|
pub type RawDefaultAttestation = RawEpidAttestation;
|
||||||
|
|
||||||
|
#[cfg(feature = "mock-sgx")]
|
||||||
|
pub type DefaultAttestation = MockAttestation;
|
||||||
|
#[cfg(feature = "mock-sgx")]
|
||||||
|
pub type RawDefaultAttestation = RawMockAttestation;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
msg::HasDomainType,
|
msg::HasDomainType,
|
||||||
state::{MrEnclave, UserData},
|
state::{MrEnclave, UserData},
|
||||||
|
@ -137,22 +149,28 @@ impl Attestation for EpidAttestation {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct MockAttestation;
|
pub struct MockAttestation(pub UserData);
|
||||||
|
|
||||||
|
impl Default for MockAttestation {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self([0u8; 64])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct RawMockAttestation;
|
pub struct RawMockAttestation(pub HexBinary);
|
||||||
|
|
||||||
impl TryFrom<RawMockAttestation> for MockAttestation {
|
impl TryFrom<RawMockAttestation> for MockAttestation {
|
||||||
type Error = StdError;
|
type Error = StdError;
|
||||||
|
|
||||||
fn try_from(_value: RawMockAttestation) -> Result<Self, Self::Error> {
|
fn try_from(value: RawMockAttestation) -> Result<Self, Self::Error> {
|
||||||
Ok(Self)
|
Ok(Self(value.0.to_array()?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MockAttestation> for RawMockAttestation {
|
impl From<MockAttestation> for RawMockAttestation {
|
||||||
fn from(_value: MockAttestation) -> Self {
|
fn from(value: MockAttestation) -> Self {
|
||||||
Self
|
Self(value.0.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,13 +180,13 @@ impl HasDomainType for RawMockAttestation {
|
||||||
|
|
||||||
impl HasUserData for MockAttestation {
|
impl HasUserData for MockAttestation {
|
||||||
fn user_data(&self) -> UserData {
|
fn user_data(&self) -> UserData {
|
||||||
unimplemented!("MockAttestation handler is a noop")
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Attestation for MockAttestation {
|
impl Attestation for MockAttestation {
|
||||||
fn mr_enclave(&self) -> MrEnclave {
|
fn mr_enclave(&self) -> MrEnclave {
|
||||||
unimplemented!("MockAttestation handler is a noop")
|
Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use sha2::{Digest, Sha256};
|
||||||
use crate::{
|
use crate::{
|
||||||
msg::{
|
msg::{
|
||||||
execute::attested::{
|
execute::attested::{
|
||||||
Attested, EpidAttestation, HasUserData, RawAttested, RawEpidAttestation,
|
Attested, DefaultAttestation, HasUserData, RawAttested, RawDefaultAttestation,
|
||||||
},
|
},
|
||||||
HasDomainType,
|
HasDomainType,
|
||||||
},
|
},
|
||||||
|
@ -13,10 +13,10 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Instantiate<A = EpidAttestation>(pub Attested<CoreInstantiate, A>);
|
pub struct Instantiate<A = DefaultAttestation>(pub Attested<CoreInstantiate, A>);
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct RawInstantiate<RA = RawEpidAttestation>(RawAttested<RawCoreInstantiate, RA>);
|
pub struct RawInstantiate<RA = RawDefaultAttestation>(RawAttested<RawCoreInstantiate, RA>);
|
||||||
|
|
||||||
impl<RA> TryFrom<RawInstantiate<RA>> for Instantiate<RA::DomainType>
|
impl<RA> TryFrom<RawInstantiate<RA>> for Instantiate<RA::DomainType>
|
||||||
where
|
where
|
||||||
|
|
|
@ -9,6 +9,9 @@ repository.workspace = true
|
||||||
keywords = ["blockchain", "cosmos", "tendermint", "cycles", "quartz"]
|
keywords = ["blockchain", "cosmos", "tendermint", "cycles", "quartz"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
mock-sgx = ["quartz-cw/mock-sgx"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# external
|
# external
|
||||||
clap.workspace = true
|
clap.workspace = true
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage: $0 <REQUEST> <REQUEST_MSG>"
|
echo "Usage: $0 <REQUEST> <REQUEST_MSG>"
|
||||||
echo " <REQUEST>: Instantiate | SessionCreate | SessionSetPubKey"
|
echo " <REQUEST>: Instantiate | SessionCreate | SessionSetPubKey"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
ROOT=${ROOT:-$HOME}
|
ROOT=${ROOT:-$HOME}
|
||||||
|
@ -23,9 +23,6 @@ REQUEST_MSG=${2:-"{}"}
|
||||||
# Use the QUARTZ_PORT environment variable if set, otherwise default to 11090
|
# Use the QUARTZ_PORT environment variable if set, otherwise default to 11090
|
||||||
QUARTZ_PORT="${QUARTZ_PORT:-11090}"
|
QUARTZ_PORT="${QUARTZ_PORT:-11090}"
|
||||||
|
|
||||||
# clear tmp files from previous runs
|
|
||||||
rm -f "$QUOTE_FILE" "$REPORT_FILE" "$REPORT_SIG_FILE"
|
|
||||||
|
|
||||||
# query the gRPC quartz enclave service
|
# query the gRPC quartz enclave service
|
||||||
ATTESTED_MSG=$(grpcurl -plaintext -import-path "$DIR_PROTO" -proto quartz.proto -d "$REQUEST_MSG" "127.0.0.1:$QUARTZ_PORT" quartz.Core/"$REQUEST" | jq -c '.message | fromjson')
|
ATTESTED_MSG=$(grpcurl -plaintext -import-path "$DIR_PROTO" -proto quartz.proto -d "$REQUEST_MSG" "127.0.0.1:$QUARTZ_PORT" quartz.Core/"$REQUEST" | jq -c '.message | fromjson')
|
||||||
|
|
||||||
|
@ -33,6 +30,29 @@ ATTESTED_MSG=$(grpcurl -plaintext -import-path "$DIR_PROTO" -proto quartz.proto
|
||||||
QUOTE=$(echo "$ATTESTED_MSG" | jq -c '.quote')
|
QUOTE=$(echo "$ATTESTED_MSG" | jq -c '.quote')
|
||||||
MSG=$(echo "$ATTESTED_MSG" | jq 'del(.quote)')
|
MSG=$(echo "$ATTESTED_MSG" | jq 'del(.quote)')
|
||||||
|
|
||||||
|
if [ -n "$MOCK_SGX" ]; then
|
||||||
|
case "$REQUEST" in
|
||||||
|
"Instantiate")
|
||||||
|
jq -nc --argjson msg "$MSG" --argjson "attestation" \
|
||||||
|
"$QUOTE" \
|
||||||
|
'$ARGS.named' ;;
|
||||||
|
|
||||||
|
"SessionCreate" | "SessionSetPubKey")
|
||||||
|
REQUEST_KEY=$(echo "$REQUEST" | perl -pe 's/([A-Z])/_\L$1/g;s/^_//') #sed 's/\([A-Z]\)/_\L\1/g;s/^_//')
|
||||||
|
jq -nc --argjson quartz "$(jq -nc --argjson "$REQUEST_KEY" "$(jq -nc --argjson msg "$MSG" --argjson attestation \
|
||||||
|
"$QUOTE" '$ARGS.named')" '$ARGS.named')" '$ARGS.named' ;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
usage ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# clear tmp files from previous runs
|
||||||
|
rm -f "$QUOTE_FILE" "$REPORT_FILE" "$REPORT_SIG_FILE"
|
||||||
|
|
||||||
# request the IAS report for EPID attestations
|
# request the IAS report for EPID attestations
|
||||||
echo -n "$QUOTE" | xxd -r -p - > "$QUOTE_FILE"
|
echo -n "$QUOTE" | xxd -r -p - > "$QUOTE_FILE"
|
||||||
gramine-sgx-ias-request report -g "$RA_CLIENT_SPID" -k "$IAS_API_KEY" -q "$QUOTE_FILE" -r "$REPORT_FILE" -s "$REPORT_SIG_FILE" > /dev/null 2>&1
|
gramine-sgx-ias-request report -g "$RA_CLIENT_SPID" -k "$IAS_API_KEY" -q "$QUOTE_FILE" -r "$REPORT_FILE" -s "$REPORT_SIG_FILE" > /dev/null 2>&1
|
||||||
|
@ -44,17 +64,17 @@ REPORTSIG=$(cat "$REPORT_SIG_FILE" | tr -d '\r')
|
||||||
#echo "$REPORTSIG"
|
#echo "$REPORTSIG"
|
||||||
|
|
||||||
case "$REQUEST" in
|
case "$REQUEST" in
|
||||||
"Instantiate")
|
"Instantiate")
|
||||||
jq -nc --argjson msg "$MSG" --argjson "attestation" \
|
jq -nc --argjson msg "$MSG" --argjson "attestation" \
|
||||||
"$(jq -nc --argjson report "$(jq -nc --argjson report "$REPORT" --arg reportsig "$REPORTSIG" '$ARGS.named')" '$ARGS.named')" \
|
"$(jq -nc --argjson report "$(jq -nc --argjson report "$REPORT" --arg reportsig "$REPORTSIG" '$ARGS.named')" '$ARGS.named')" \
|
||||||
'$ARGS.named' ;;
|
'$ARGS.named' ;;
|
||||||
|
|
||||||
"SessionCreate" | "SessionSetPubKey")
|
"SessionCreate" | "SessionSetPubKey")
|
||||||
REQUEST_KEY=$(echo "$REQUEST" | sed 's/\([A-Z]\)/_\L\1/g;s/^_//')
|
REQUEST_KEY=$(echo "$REQUEST" | perl -pe 's/([A-Z])/_\L$1/g;s/^_//')
|
||||||
jq -nc --argjson quartz "$(jq -nc --argjson "$REQUEST_KEY" "$(jq -nc --argjson msg "$MSG" --argjson attestation \
|
jq -nc --argjson quartz "$(jq -nc --argjson "$REQUEST_KEY" "$(jq -nc --argjson msg "$MSG" --argjson attestation \
|
||||||
"$(jq -nc --argjson report "$(jq -nc --argjson report "$REPORT" --arg reportsig "$REPORTSIG" '$ARGS.named')" '$ARGS.named')" \
|
"$(jq -nc --argjson report "$(jq -nc --argjson report "$REPORT" --arg reportsig "$REPORTSIG" '$ARGS.named')" '$ARGS.named')" \
|
||||||
'$ARGS.named')" '$ARGS.named')" '$ARGS.named' ;;
|
'$ARGS.named')" '$ARGS.named')" '$ARGS.named' ;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
usage ;;
|
usage ;;
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
mod cli;
|
mod cli;
|
||||||
|
|
||||||
use std::{
|
use std::{error::Error, fs::File, io::Read};
|
||||||
error::Error,
|
|
||||||
fs::{read_to_string, File},
|
|
||||||
io::{Read, Write},
|
|
||||||
process::Command,
|
|
||||||
};
|
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use cosmos_sdk_proto::{
|
use cosmos_sdk_proto::{
|
||||||
|
@ -30,14 +25,12 @@ use cosmrs::{
|
||||||
};
|
};
|
||||||
use ecies::{PublicKey, SecretKey};
|
use ecies::{PublicKey, SecretKey};
|
||||||
use quartz_cw::msg::{
|
use quartz_cw::msg::{
|
||||||
execute::attested::{Attested, EpidAttestation},
|
execute::attested::Attested,
|
||||||
instantiate::{CoreInstantiate, RawInstantiate},
|
instantiate::{CoreInstantiate, RawInstantiate},
|
||||||
InstantiateMsg,
|
InstantiateMsg,
|
||||||
};
|
};
|
||||||
use quartz_proto::quartz::{core_client::CoreClient, InstantiateRequest};
|
use quartz_proto::quartz::{core_client::CoreClient, InstantiateRequest};
|
||||||
use quartz_relayer::types::InstantiateResponse;
|
use quartz_relayer::types::InstantiateResponse;
|
||||||
use quartz_tee_ra::IASReport;
|
|
||||||
use serde_json::{json, Value};
|
|
||||||
use subtle_encoding::base64;
|
use subtle_encoding::base64;
|
||||||
use tendermint::public_key::Secp256k1 as TmPublicKey;
|
use tendermint::public_key::Secp256k1 as TmPublicKey;
|
||||||
|
|
||||||
|
@ -50,16 +43,32 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut client = CoreClient::connect(args.enclave_addr.uri().to_string()).await?;
|
let mut client = CoreClient::connect(args.enclave_addr.uri().to_string()).await?;
|
||||||
let response = client.instantiate(InstantiateRequest {}).await?;
|
let response = client.instantiate(InstantiateRequest {}).await?;
|
||||||
let response: InstantiateResponse = response.into_inner().try_into()?;
|
let response: InstantiateResponse = response.into_inner().try_into()?;
|
||||||
let (config, quote) = response.into_message().into_tuple();
|
|
||||||
|
|
||||||
let ias_report = gramine_sgx_ias_report("e)?;
|
#[cfg(feature = "mock-sgx")]
|
||||||
println!(
|
let attestation = {
|
||||||
"{}",
|
use quartz_cw::msg::execute::attested::MockAttestation;
|
||||||
serde_json::to_string(&ias_report).expect("infallible serializer")
|
|
||||||
|
MockAttestation::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock-sgx"))]
|
||||||
|
let attestation = {
|
||||||
|
use quartz_cw::msg::execute::attested::EpidAttestation;
|
||||||
|
use quartz_tee_ra::IASReport;
|
||||||
|
|
||||||
|
let ias_report = gramine_sgx_ias_report(response.quote())?;
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
serde_json::to_string(&ias_report).expect("infallible serializer")
|
||||||
|
);
|
||||||
|
let ias_report: IASReport = serde_json::from_str(&ias_report.to_string())?;
|
||||||
|
EpidAttestation::new(ias_report)
|
||||||
|
};
|
||||||
|
|
||||||
|
let cw_instantiate_msg = Attested::new(
|
||||||
|
CoreInstantiate::new(response.into_message().into_tuple().0),
|
||||||
|
attestation,
|
||||||
);
|
);
|
||||||
let ias_report: IASReport = serde_json::from_str(&ias_report.to_string())?;
|
|
||||||
let attestation = EpidAttestation::new(ias_report);
|
|
||||||
let cw_instantiate_msg = Attested::new(CoreInstantiate::new(config), attestation);
|
|
||||||
|
|
||||||
// Read the TSP secret
|
// Read the TSP secret
|
||||||
let secret = {
|
let secret = {
|
||||||
|
@ -152,7 +161,14 @@ pub async fn send_tx(node: impl ToString, tx_bytes: Vec<u8>) -> Result<(), Box<d
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gramine_sgx_ias_report(quote: &[u8]) -> Result<Value, Box<dyn Error>> {
|
#[cfg(not(feature = "mock-sgx"))]
|
||||||
|
fn gramine_sgx_ias_report(quote: &[u8]) -> Result<serde_json::Value, Box<dyn Error>> {
|
||||||
|
use std::{
|
||||||
|
fs::{read_to_string, File},
|
||||||
|
io::Write,
|
||||||
|
process::Command,
|
||||||
|
};
|
||||||
|
|
||||||
let dir = tempfile::tempdir()?;
|
let dir = tempfile::tempdir()?;
|
||||||
let quote_file_path = dir.path().join("test.quote");
|
let quote_file_path = dir.path().join("test.quote");
|
||||||
let datareport_file_path = dir.path().join("datareport");
|
let datareport_file_path = dir.path().join("datareport");
|
||||||
|
@ -173,6 +189,6 @@ fn gramine_sgx_ias_report(quote: &[u8]) -> Result<Value, Box<dyn Error>> {
|
||||||
|
|
||||||
let report = read_to_string(datareport_file_path)?;
|
let report = read_to_string(datareport_file_path)?;
|
||||||
let report_sig = read_to_string(datareportsig_file_path)?;
|
let report_sig = read_to_string(datareportsig_file_path)?;
|
||||||
let ias_report = json!({"report": report, "reportsig": report_sig});
|
let ias_report = serde_json::json!({"report": report, "reportsig": report_sig});
|
||||||
Ok(ias_report)
|
Ok(ias_report)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue