124 lines
4.2 KiB
Rust
124 lines
4.2 KiB
Rust
use cw_client::{GrpcClient, CwClient};
|
|
use quartz_tcbinfo_msgs::{QueryMsg, ExecuteMsg};
|
|
use quoted_string::strip_dquotes;
|
|
use anyhow::{anyhow, Result};
|
|
use quoted_string::test_utils::TestSpec;
|
|
use quoted_string::to_content;
|
|
use reqwest::Url;
|
|
use serde_json::{json, Value};
|
|
use std::env;
|
|
use tendermint::chain::id::Id;
|
|
|
|
type Fmspc = String;
|
|
type Update = String;
|
|
|
|
const TCB_SIGNER: &str = include_str!("../tcb_signer.pem");
|
|
|
|
async fn get_tcbinfo(fmspc: Fmspc, update: Update) -> String {
|
|
let url = format!("https://api.trustedservices.intel.com/sgx/certification/v4/tcb?fmspc={fmspc}&update={update}");
|
|
let body: String = reqwest::get(url)
|
|
.await
|
|
.expect("url retrieval failed")
|
|
.text()
|
|
.await
|
|
.expect("could not read https response");
|
|
body
|
|
}
|
|
|
|
async fn get_fmspc_list() -> Vec<Fmspc> {
|
|
let body: String =
|
|
reqwest::get("https://api.trustedservices.intel.com/sgx/certification/v4/fmspcs")
|
|
.await
|
|
.expect("url retrieval failed")
|
|
.text()
|
|
.await
|
|
.expect("could not read https response");
|
|
let fmspc_data: Vec<Value> = serde_json::from_str(&body).expect("could not convert to JSON");
|
|
let mut fmspc_list: Vec<Fmspc> = Vec::new();
|
|
for item in fmspc_data.iter() {
|
|
let fmspc: String = format!("{}", item["fmspc"]);
|
|
fmspc_list.push(strip_dquotes(&fmspc).unwrap().to_string());
|
|
}
|
|
fmspc_list
|
|
}
|
|
|
|
async fn upsert_tcbinfo(url: &str, contract_addr: &str, chain_id : Id, sender: &str, gas: u64, fees: &str, sk: &str) -> Result<(), &'static str> {
|
|
|
|
let network = Url::parse(url).expect("couldn't parse network URL");
|
|
let skey = hex::decode(sk).expect("couldn't read signing key")
|
|
.as_slice()
|
|
.try_into()
|
|
.map_err(|e| anyhow!("failed to read/parse sk: {}", e)).expect("couldn't extract result value");
|
|
let client = GrpcClient::new(skey, network);
|
|
let fmspc_list = get_fmspc_list().await;
|
|
|
|
for fmspc in fmspc_list {
|
|
|
|
let tcbinfo_from_api = get_tcbinfo(fmspc.clone(), "standard".to_string()).await;
|
|
|
|
// assert!(verify_signature(tcbinfo.clone(), key));
|
|
let contract_address = contract_addr
|
|
.parse()
|
|
.expect("failed to parse contract address");
|
|
let query_msg = QueryMsg::GetTcbInfo { fmspc: fmspc.clone() };
|
|
|
|
let tcbinfo_on_chain = { if let Ok(res) = client.query_smart::<Value>(&contract_address, json!(query_msg)).await {
|
|
to_content::<TestSpec>(&res["data"]["tcb_info"].to_string()).unwrap().to_string()
|
|
} else {
|
|
"".to_string()
|
|
}
|
|
|
|
|
|
};
|
|
|
|
if tcbinfo_on_chain != tcbinfo_from_api {
|
|
println!("updating on-chain TCBInfo for FMSPC: {fmspc}");
|
|
|
|
|
|
let execute_msg = ExecuteMsg {
|
|
tcb_info: tcbinfo_from_api.to_string(),
|
|
certificate: TCB_SIGNER.to_string(),
|
|
time: None,
|
|
};
|
|
let res = client
|
|
.tx_execute(
|
|
&contract_address,
|
|
&chain_id,
|
|
gas,
|
|
sender,
|
|
json!(execute_msg),
|
|
fees
|
|
)
|
|
.await;
|
|
println!("{res:?}");
|
|
std::thread::sleep(std::time::Duration::from_secs(5));
|
|
} else {
|
|
println!("TCBInfo for FMSPC: {fmspc} up to date")
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::main]
|
|
pub async fn main() {
|
|
let args: Vec<String> = env::args().collect();
|
|
let url = &args[1];
|
|
let chain_id = &args[2];
|
|
let contract_address : &str = &args[3];
|
|
let sender: &str = &args[4];
|
|
let gas: &u64 = &args[5].parse().expect("gas must be a u64 value");
|
|
let fees: &str = &args[6];
|
|
let sk: &str = &args[7];
|
|
upsert_tcbinfo(url, contract_address, Id::try_from(chain_id.clone()).expect("invalid chain id"), sender, *gas, fees, sk).await.expect("TCBInfo update failed");
|
|
}
|
|
|
|
/*let url =;
|
|
let chain_id = tendermint::chain::id::Id::try_from("pion-1").expect("invalid chain id");
|
|
contract_address = ;
|
|
let sender = ;
|
|
gas = 1000000,
|
|
fees = ,
|
|
*/
|
|
|
|
|