cycles-quartz/crates/utils/tcbinfo-updater/src/main.rs
2024-12-05 14:36:19 +01:00

98 lines
3.3 KiB
Rust

use cw_client::{CliClient, CwClient};
use mc_attestation_verifier::SignedTcbInfo;
use p256::ecdsa::VerifyingKey;
use quartz_tcbinfo_msgs::{QueryMsg, ExecuteMsg};
use quoted_string::strip_dquotes;
use reqwest::Url;
use serde_json::{json, Value};
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());
}
println!("{:?}", fmspc_list);
fmspc_list
}
async fn upsert_tcbinfo() -> Result<(), &'static str> {
let testnet = Url::parse("https://rpc-falcron.pion-1.ntrn.tech").expect("couldn't parse network URL");
let client = CliClient::neutrond(testnet);
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 =
"neutron1r4m59786vmxrx866585ze5ugjx9egcyja0nuxhn2y6d7ht6680sspa89zk"
.parse()
.expect("failed to parse contract address");
let query_msg = QueryMsg::GetTcbInfo { fmspc },
let tcbinfo_on_chain: Value = client.query_smart(&contract_address, json!(query_msg)).await.expect("contract query failed");
println!("{tcbinfo_on_chain:?}");
if tcbinfo_on_chain.to_string() != tcbinfo_from_api {
println!("updating on-chain TCBInfo for FMSPC: {fmspc}");
let chain_id = tendermint::chain::id::Id::try_from("pion-1").expect("invalid chain id");
let sender = "ajinkya";
let execute_msg = ExecuteMsg {
tcb_info: tcbinfo_from_api.to_string(),
certificate: TCB_SIGNER.to_string(),
time: None,
};
let _ = client
.tx_execute(
&contract_address,
&chain_id,
1000000,
sender,
json!(execute_msg),
"11000untrn",
)
.await;
println!("done");
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() {
upsert_tcbinfo().await.expect("TCBInfo update failed");
}