Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix generate-key to create a report that contains the EK #110

Merged
merged 6 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading