Skip to content

Commit

Permalink
Merge pull request #110 from datachainlab/fix-gen-ek
Browse files Browse the repository at this point in the history
Fix `generate-key` to create a report that contains the EK

Signed-off-by: Jun Kimura <[email protected]>
  • Loading branch information
bluele authored Sep 23, 2024
2 parents 69ffe7d + b08f9f1 commit e58a1e6
Show file tree
Hide file tree
Showing 32 changed files with 476 additions and 344 deletions.
6 changes: 5 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 0 additions & 29 deletions app/src/commands/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,11 @@ pub struct IASRemoteAttestation {
help = "An enclave key attested by Remote Attestation"
)]
pub enclave_key: String,
/// An operator address to perform `registerEnclaveKey` transaction on-chain
#[clap(
long = "operator",
help = "An operator address to perform `registerEnclaveKey` transaction on-chain"
)]
pub operator: Option<String>,
/// IAS mode
#[clap(long = "development", help = "Use IAS development mode")]
pub is_dev: bool,
}

impl IASRemoteAttestation {
fn get_operator(&self) -> Result<Option<Address>> {
if let Some(operator) = &self.operator {
Ok(Some(Address::from_hex_string(operator)?))
} else {
Ok(None)
}
}
}

fn run_ias_remote_attestation<E: EnclaveCommandAPI<S>, S: CommitStore>(
enclave: E,
cmd: &IASRemoteAttestation,
Expand All @@ -95,7 +79,6 @@ fn run_ias_remote_attestation<E: EnclaveCommandAPI<S>, S: CommitStore>(
match ias::run_ias_ra(
&enclave,
target_enclave_key,
cmd.get_operator()?,
if cmd.is_dev {
IASMode::Development
} else {
Expand Down Expand Up @@ -179,17 +162,6 @@ pub struct SimulateRemoteAttestation {
pub isv_enclave_quote_status: String,
}

#[cfg(feature = "sgx-sw")]
impl SimulateRemoteAttestation {
fn get_operator(&self) -> Result<Option<Address>> {
if let Some(operator) = &self.operator {
Ok(Some(Address::from_hex_string(operator)?))
} else {
Ok(None)
}
}
}

#[cfg(feature = "sgx-sw")]
fn run_simulate_remote_attestation<E: EnclaveCommandAPI<S>, S: CommitStore>(
enclave: E,
Expand Down Expand Up @@ -242,7 +214,6 @@ fn run_simulate_remote_attestation<E: EnclaveCommandAPI<S>, S: CommitStore>(
match remote_attestation::ias_simulation::run_ias_ra_simulation(
&enclave,
target_enclave_key,
cmd.get_operator()?,
cmd.advisory_ids.clone(),
cmd.isv_enclave_quote_status.clone(),
signing_key,
Expand Down
33 changes: 28 additions & 5 deletions app/src/commands/enclave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
};
use anyhow::{anyhow, Result};
use clap::Parser;
use crypto::Address;
use ecall_commands::GenerateEnclaveKeyInput;
use enclave_api::{Enclave, EnclaveCommandAPI, EnclaveProtoAPI};
use lcp_types::Mrenclave;
Expand Down Expand Up @@ -59,14 +60,36 @@ pub struct GenerateKey {
/// Options for enclave
#[clap(flatten)]
pub enclave: EnclaveOpts,
/// An operator address to perform `registerEnclaveKey` transaction on-chain
#[clap(
long = "operator",
help = "An operator address to perform `registerEnclaveKey` transaction on-c
hain"
)]
pub operator: Option<String>,
// TODO add target qe option
}

impl GenerateKey {
fn get_operator(&self) -> Result<Option<Address>> {
if let Some(operator) = &self.operator {
Ok(Some(Address::from_hex_string(operator)?))
} else {
Ok(None)
}
}
}

fn run_generate_key<E: EnclaveCommandAPI<S>, S: CommitStore>(
enclave: E,
_: &GenerateKey,
input: &GenerateKey,
) -> Result<()> {
let (target_info, _) = remote_attestation::init_quote()?;
let res = enclave
.generate_enclave_key(GenerateEnclaveKeyInput)
.generate_enclave_key(GenerateEnclaveKeyInput {
target_info,
operator: input.get_operator()?,
})
.map_err(|e| anyhow!("failed to generate an enclave key: {:?}", e))?;
println!("{}", res.pub_key.as_address());
Ok(())
Expand Down Expand Up @@ -97,9 +120,9 @@ fn run_list_keys<E: EnclaveCommandAPI<S>, S: CommitStore>(
};
let mut list_json = Vec::new();
for eki in list {
match eki.avr {
Some(eavr) => {
let avr = eavr.get_avr()?;
match eki.signed_avr {
Some(signed_avr) => {
let avr = signed_avr.get_avr()?;
let report_data = avr.parse_quote()?.report_data();
list_json.push(json! {{
"address": eki.address.to_hex_string(),
Expand Down
15 changes: 13 additions & 2 deletions enclave-modules/ecall-handler/src/enclave_manage/enclave.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
use crate::enclave_manage::Error;
use crate::prelude::*;
use attestation_report::ReportData;
use crypto::{EnclaveKey, SealingKey};
use ecall_commands::{GenerateEnclaveKeyInput, GenerateEnclaveKeyResponse};
use sgx_tse::rsgx_create_report;

pub(crate) fn generate_enclave_key(
_: GenerateEnclaveKeyInput,
input: GenerateEnclaveKeyInput,
) -> Result<GenerateEnclaveKeyResponse, Error> {
let ek = EnclaveKey::new()?;
let sealed_ek = ek.seal()?;
let ek_pub = ek.get_pubkey();
let report_data = ReportData::new(ek_pub.as_address(), input.operator);
let report = match rsgx_create_report(&input.target_info, &report_data.into()) {
Ok(r) => r,
Err(e) => {
return Err(Error::sgx_error(e, "Report creation => failed".to_string()));
}
};
Ok(GenerateEnclaveKeyResponse {
pub_key: ek.get_pubkey(),
pub_key: ek_pub,
sealed_ek,
report,
})
}
1 change: 0 additions & 1 deletion enclave-modules/ecall-handler/src/enclave_manage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ pub use router::dispatch;

mod enclave;
mod errors;
mod report;
mod router;
23 changes: 0 additions & 23 deletions enclave-modules/ecall-handler/src/enclave_manage/report.rs

This file was deleted.

13 changes: 2 additions & 11 deletions enclave-modules/ecall-handler/src/enclave_manage/router.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
use crate::enclave_manage::report::create_report;
use crate::enclave_manage::{enclave::generate_enclave_key, Error};
use crate::prelude::*;
use ecall_commands::{
CommandContext, CommandResponse, EnclaveManageCommand, EnclaveManageResponse,
};
use ecall_commands::{CommandResponse, EnclaveManageCommand, EnclaveManageResponse};

pub fn dispatch(
cctx: CommandContext,
command: EnclaveManageCommand,
) -> Result<CommandResponse, Error> {
pub fn dispatch(command: EnclaveManageCommand) -> Result<CommandResponse, Error> {
use EnclaveManageCommand::*;

let res = match command {
GenerateEnclaveKey(input) => CommandResponse::EnclaveManage(
EnclaveManageResponse::GenerateEnclaveKey(generate_enclave_key(input)?),
),
CreateReport(input) => CommandResponse::EnclaveManage(EnclaveManageResponse::CreateReport(
create_report(cctx, input)?,
)),
};
Ok(res)
}
2 changes: 1 addition & 1 deletion enclave-modules/ecall-handler/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use enclave_environment::Env;
pub fn dispatch<E: Env>(env: E, command: ECallCommand) -> Result<CommandResponse> {
match command.cmd {
Command::EnclaveManage(cmd) => {
enclave_manage::dispatch(command.ctx, cmd).map_err(Error::enclave_manage_command)
enclave_manage::dispatch(cmd).map_err(Error::enclave_manage_command)
}
Command::LightClient(cmd) => {
light_client::dispatch(env, command.ctx, cmd).map_err(Error::light_client_command)
Expand Down
1 change: 1 addition & 0 deletions enclave/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion modules/attestation-report/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub use errors::Error;
mod errors;

pub use report::{
AttestationVerificationReport, EndorsedAttestationVerificationReport, Quote, ReportData,
AttestationVerificationReport, Quote, ReportData, SignedAttestationVerificationReport,
};
mod report;

Expand Down
28 changes: 21 additions & 7 deletions modules/attestation-report/src/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub const REPORT_DATA_V1: u8 = 1;
pub struct ReportData([u8; 64]);

impl ReportData {
/// Creates a new report data
pub fn new(ek: Address, operator: Option<Address>) -> Self {
let mut data: ReportData = Default::default();
data.0[0] = REPORT_DATA_V1;
Expand All @@ -26,16 +27,23 @@ impl ReportData {
data
}

/// Returns the enclave key from the report data
///
/// CONTRACT: The report data must be validated before calling this function
pub fn enclave_key(&self) -> Address {
// Unwrap is safe because the size of the slice is 20
Address::try_from(&self.0[1..21]).unwrap()
}

/// Returns the operator from the report data
///
/// CONTRACT: The report data must be validated before calling this function
pub fn operator(&self) -> Address {
// Unwrap is safe because the size of the slice is 20
Address::try_from(&self.0[21..41]).unwrap()
}

/// Validates the report data
pub fn validate(&self) -> Result<(), Error> {
if self.0[0] != REPORT_DATA_V1 {
return Err(Error::unexpected_report_data_version(
Expand Down Expand Up @@ -71,25 +79,31 @@ impl From<sgx_report_data_t> for ReportData {
}
}

/// AttestationReport can be endorsed by either the Intel Attestation Service
/// using EPID or Data Center Attestation
/// Service (platform dependent) using ECDSA.
/// SignedAttestationVerificationReport represents the signed attestation verification report from Intel
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct EndorsedAttestationVerificationReport {
/// Attestation report generated by the hardware
pub struct SignedAttestationVerificationReport {
/// A report generated by the Intel Attestation Service
pub avr: String,
/// Singature of the report
/// Signature of the report
#[serde(with = "serde_base64")]
pub signature: Vec<u8>,
/// Certificate matching the signing key of the signature
#[serde(with = "serde_base64")]
pub signing_cert: Vec<u8>,
}

impl EndorsedAttestationVerificationReport {
impl SignedAttestationVerificationReport {
pub fn get_avr(&self) -> Result<AttestationVerificationReport, Error> {
serde_json::from_slice(self.avr.as_ref()).map_err(Error::serde_json)
}

pub fn to_json(&self) -> Result<String, Error> {
serde_json::to_string(self).map_err(Error::serde_json)
}

pub fn from_json(json: &str) -> Result<Self, Error> {
serde_json::from_str(json).map_err(Error::serde_json)
}
}

// AttestationVerificationReport represents Intel's Attestation Verification Report
Expand Down
4 changes: 2 additions & 2 deletions modules/attestation-report/src/verification.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::prelude::*;
use crate::{errors::Error, EndorsedAttestationVerificationReport};
use crate::{errors::Error, SignedAttestationVerificationReport};
use lcp_types::{nanos_to_duration, Time};

pub const IAS_REPORT_CA: &[u8] =
Expand All @@ -22,7 +22,7 @@ static SUPPORTED_SIG_ALGS: SignatureAlgorithms = &[

pub fn verify_report(
current_timestamp: Time,
report: &EndorsedAttestationVerificationReport,
report: &SignedAttestationVerificationReport,
) -> Result<(), Error> {
// NOTE: Currently, webpki::Time's constructor only accepts seconds as unix timestamp.
// Therefore, the current time are rounded up conservatively.
Expand Down
2 changes: 1 addition & 1 deletion modules/ecall-commands/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub enum Command {
impl EnclaveKeySelector for Command {
fn get_enclave_key(&self) -> Option<crypto::Address> {
match self {
Self::EnclaveManage(cmd) => cmd.get_enclave_key(),
Self::EnclaveManage(_) => None,
Self::LightClient(cmd) => cmd.get_enclave_key(),
}
}
Expand Down
Loading

0 comments on commit e58a1e6

Please sign in to comment.