cycles-quartz/crates/utils/tcbinfo-updater/src/main.rs

98 lines
3.5 KiB
Rust
Raw Normal View History

2024-11-29 19:07:22 +00:00
use quoted_string::strip_dquotes;
use serde_json::Value;
use std::collections::HashMap;
use std::fs;
2024-11-29 19:07:22 +00:00
use cw_client::{CliClient, CwClient};
use reqwest::Url;
use quartz_tcbinfo_msgs::ExecuteMsg;
2024-11-29 19:07:22 +00:00
type TcbInfo = Value;
type Fmspc = String;
type Update = String;
2024-11-29 19:07:22 +00:00
const TCB_SIGNER: &str = include_str!("../tcb_signer.pem");
struct ExecMsg {
msg: ExecuteMsg
}
impl ToString for ExecMsg {
fn to_string (&self) -> String {
format!("\"tcb_info\": {0}, \"certificate\": {1}", self.msg.tcb_info, self.msg.certificate)
}
}
2024-12-03 09:13:37 +00:00
async fn get_tcbinfo(fmspc: Fmspc, update: Update) -> Value {
2024-11-29 19:07:22 +00:00
let url = format!("https://api.trustedservices.intel.com/sgx/certification/v4/tcb?fmspc={fmspc}&update={update}");
2024-12-03 09:13:37 +00:00
let body: String = reqwest::get(url)
.await
2024-11-29 19:07:22 +00:00
.expect("url retrieval failed")
.text()
.expect("could not read https response");
let tcbinfo: Value = serde_json::from_str(&body).expect("could not convert to JSON");
tcbinfo
}
2024-12-03 09:13:37 +00:00
async fn get_fmspc_list() -> Vec<Fmspc> {
2024-11-29 19:07:22 +00:00
let body: String =
2024-12-03 09:13:37 +00:00
reqwest::get("https://api.trustedservices.intel.com/sgx/certification/v4/fmspcs").await
2024-11-29 19:07:22 +00:00
.expect("url retrieval failed")
.text()
.expect("could not read https response");
2024-11-29 19:07:22 +00:00
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());
}
println!("{:?}", fmspc_list);
fmspc_list
}
2024-12-03 09:13:37 +00:00
async fn upsert_tcbinfo() -> Result<(), &'static str> {
2024-11-29 19:07:22 +00:00
let data = fs::read_to_string("./standard").expect("Unable to read file");
let mut store: HashMap<Fmspc, TcbInfo> = serde_json::from_str(&data).unwrap();
2024-11-29 19:07:22 +00:00
let fmspc_list = get_fmspc_list();
for fmspc in fmspc_list {
let tcbinfo = get_tcbinfo(fmspc.clone(), "standard".to_string());
let store_entry = &store[&fmspc];
if *store_entry != tcbinfo {
2024-11-29 19:07:22 +00:00
println!("updating local TCBInfo for FMSPC: {fmspc}");
store.insert(fmspc.clone(), tcbinfo.clone());
println!("updating on-chain TCBInfo for FMSPC: {fmspc}");
let testnet = Url::parse("https://rpc-falcron.pion-1.ntrn.tech").expect("couldn't parse network URL");
let contract_address = cosmrs::AccountId::new("neutrontcbinfo", "neutron1r4m59786vmxrx866585ze5ugjx9egcyja0nuxhn2y6d7ht6680sspa89zk".as_bytes()).expect("failed to parse contract address");
let chain_id = tendermint::chain::id::Id::try_from("pion-1").expect("invalid chain id");
2024-11-29 19:07:22 +00:00
let sender = "ajinkya";
2024-11-29 19:07:22 +00:00
let client = CliClient::neutrond(testnet);
2024-11-29 19:07:22 +00:00
let execute_msg = ExecMsg { msg: ExecuteMsg {
tcb_info: tcbinfo.to_string(),
certificate: TCB_SIGNER.to_string(),
time: None,
}};
2024-12-03 09:13:37 +00:00
if let Err(e) =
client.tx_execute(&contract_address, &chain_id, 200000, &sender, execute_msg, "200000untrn").await
{
eprintln!("Error: {}", e);
}
2024-11-29 19:07:22 +00:00
println!("done");
2024-11-29 19:07:22 +00:00
}
else {
2024-11-29 19:07:22 +00:00
println!("TCBInfo for FMSPC: {fmspc} up to date")
2024-11-29 19:07:22 +00:00
}
}
2024-11-29 19:07:22 +00:00
let serialized = serde_json::to_string(&store).unwrap();
fs::write("./standard", serialized).expect("Unable to write file");
Ok(())
2024-11-29 19:07:22 +00:00
// }
// }
}
2024-11-29 19:07:22 +00:00
2024-12-03 09:13:37 +00:00
#[tokio::main]
pub async fn main() {
upsert_tcbinfo().await.expect("TCBInfo update failed");
2024-11-29 19:07:22 +00:00
}