From db821d2566af506c2a0bdf4ffb690b2ec14e47ba Mon Sep 17 00:00:00 2001 From: Alain Brenzikofer Date: Wed, 13 Sep 2023 14:26:51 +0200 Subject: [PATCH] individual extrinsics per fmspc. get certificate chain PEM from header --- Cargo.lock | 7 ++ cli/Cargo.toml | 1 + cli/README.md | 4 + .../base_cli/commands/register_tcb_info.rs | 107 ++++++++++-------- 4 files changed, 72 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c335606e9..8068839eef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2790,6 +2790,7 @@ dependencies = [ "substrate-api-client", "substrate-client-keystore", "thiserror 1.0.40", + "urlencoding", "ws", ] @@ -9132,6 +9133,12 @@ dependencies = [ "percent-encoding 2.3.0", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.4" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index f69e02b526..3a15f45a4c 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -24,6 +24,7 @@ serde_json = "1.0" sgx_crypto_helper = { branch = "master", git = "https://github.com/apache/teaclave-sgx-sdk.git" } thiserror = "1.0" ws = { version = "0.9.1", features = ["ssl"] } +urlencoding = "2.1.3" # scs / integritee my-node-runtime = { package = "integritee-node-runtime", git = "https://github.com/integritee-network/integritee-node.git", branch = "sdk-v0.12.0-polkadot-v0.9.42" } diff --git a/cli/README.md b/cli/README.md index f2bf98121c..44e89c789e 100644 --- a/cli/README.md +++ b/cli/README.md @@ -25,3 +25,7 @@ Trusted call 0x69ddfd1698bd2d629180c2dca34ce7add087526c51f43cf68245241b3f13154e Trusted call 0x69ddfd1698bd2d629180c2dca34ce7add087526c51f43cf68245241b3f13154e is Invalid ``` + +## housekeeping tasks + +populate all TCBinfo's Intel has published diff --git a/cli/src/base_cli/commands/register_tcb_info.rs b/cli/src/base_cli/commands/register_tcb_info.rs index 77f555d611..8e40cdb333 100644 --- a/cli/src/base_cli/commands/register_tcb_info.rs +++ b/cli/src/base_cli/commands/register_tcb_info.rs @@ -20,18 +20,21 @@ use crate::{ Cli, CliError, CliResult, CliResultOk, }; use itp_node_api::api_client::{ParentchainExtrinsicSigner, TEEREX}; -use itp_types::OpaqueCall; +use itp_types::{parentchain::Hash, OpaqueCall}; use itp_utils::ToHexPrefixed; use log::*; use serde::Deserialize; use serde_json::Value; use sp_core::sr25519 as sr25519_core; use std::fs::read_to_string; -use substrate_api_client::{compose_call, compose_extrinsic_offline, SubmitAndWatchUntilSuccess}; +use substrate_api_client::{ + compose_call, compose_extrinsic_offline, SubmitAndWatch, SubmitAndWatchUntilSuccess, XtStatus, +}; +use urlencoding; #[derive(Debug, Deserialize)] struct TcbInfo { - #[allow(non_snake_case_types)] + #[allow(non_snake_case)] tcbInfo: Value, signature: String, } @@ -39,19 +42,18 @@ struct TcbInfo { #[derive(Debug, Deserialize)] struct Platform { fmspc: String, - _platform: String, + #[allow(dead_code)] + platform: String, } #[derive(Parser)] pub struct RegisterTcbInfoCommand { /// Sender's parentchain AccountId in ss58check format. sender: String, - /// certificate chain PEM file - pem_file: String, /// Intel's Family-Model-Stepping-Platform-Custom SKU. 6-Byte non-prefixed hex value #[clap(short, long, action, conflicts_with = "all")] fmspc: Option, - /// registeres all fmspc currently published by Intel + /// registers all fmspc currently published by Intel #[clap(short, long, action)] all: bool, } @@ -60,11 +62,6 @@ impl RegisterTcbInfoCommand { pub(crate) fn run(&self, cli: &Cli) -> CliResult { let mut chain_api = get_chain_api(cli); - let certificate_chain_pem = match read_to_string(&self.pem_file) { - Ok(cert) => cert, - Err(e) => panic!("Opening PEM file failed: {:#?}", e), - }; - // Get the sender. let from = get_pair_from_str(&self.sender); chain_api.set_signer(ParentchainExtrinsicSigner::new(sr25519_core::Pair::from(from))); @@ -85,55 +82,71 @@ impl RegisterTcbInfoCommand { panic!("must specify either '--all' or '--fmspc'"); } }; - let calls: Vec = fmspcs + let mut nonce = chain_api.get_nonce().unwrap(); + let xt_hashes: Vec<(String, Option)> = fmspcs .into_iter() .map(|fmspc| { - trace!("fetching tcb info for fmspc {} from api.trustedservices.intel.com", fmspc); - let tcbinfo_json = reqwest::blocking::get(format!( + println!( + "fetching tcb info for fmspc {} from api.trustedservices.intel.com", + fmspc + ); + let response = reqwest::blocking::get(format!( "https://api.trustedservices.intel.com/sgx/certification/v4/tcb?fmspc={}", fmspc )) .unwrap(); - let tcb_info: TcbInfo = tcbinfo_json.json().expect("Error parsing JSON"); + //extract certificate chain from header + let certificate_chain = urlencoding::decode( + response.headers().get("TCB-Info-Issuer-Chain").unwrap().to_str().unwrap(), + ) + .unwrap() + .to_string(); + trace!("certificate chain: \n{}", certificate_chain); + + let tcb_info: TcbInfo = response.json().expect("Error parsing JSON"); + + trace!("TCB info: {:?}", tcb_info.tcbInfo); + trace!("signature: {:?}", tcb_info.signature); + let intel_signature = hex::decode(tcb_info.signature).unwrap(); - OpaqueCall::from_tuple(&compose_call!( + + let call = OpaqueCall::from_tuple(&compose_call!( chain_api.metadata(), TEEREX, "register_tcb_info", tcb_info.tcbInfo.to_string(), intel_signature, - certificate_chain_pem.clone() - )) - }) - .collect(); - let call = if calls.len() > 1 { - OpaqueCall::from_tuple(&compose_call!(chain_api.metadata(), "Utility", "batch", calls)) - } else { - calls[0].clone() - }; - trace!("encoded call to be sent as extrinsic: {}", call.to_hex()); + certificate_chain + )); - let nonce = chain_api.get_nonce().unwrap(); - let xt = compose_extrinsic_offline!( - chain_api.clone().signer().unwrap(), - call, - chain_api.extrinsic_params(nonce) - ); + trace!( + "encoded call to be sent as extrinsic with nonce {}: {}", + nonce, + call.to_hex() + ); - match chain_api.submit_and_watch_extrinsic_until_success(xt, true) { - Ok(xt_report) => { - println!( - "[+] register_tcb_info. extrinsic hash: {:?} / status: {:?} / block hash: {:?}", - xt_report.extrinsic_hash, - xt_report.status, - xt_report.block_hash.unwrap() + let xt = compose_extrinsic_offline!( + chain_api.clone().signer().unwrap(), + call, + chain_api.extrinsic_params(nonce) ); - Ok(CliResultOk::H256 { hash: xt_report.block_hash.unwrap() }) - }, - Err(e) => { - error!("register_tcb_info extrinsic failed {:?}", e); - Err(CliError::Extrinsic { msg: format!("{:?}", e) }) - }, - } + nonce += 1; + match chain_api.submit_and_watch_extrinsic_until_success(xt, false) { + Ok(xt_report) => { + println!( + "[+] register_tcb_info. extrinsic hash: {:?} / status: {:?}", + xt_report.extrinsic_hash, xt_report.status, + ); + (fmspc, Some(xt_report.extrinsic_hash)) + }, + Err(e) => { + error!("register_tcb_info extrinsic failed {:?}", e); + (fmspc, None) + }, + } + }) + .collect(); + println!("{:?}", xt_hashes); + Ok(CliResultOk::None) } }