Skip to content

Commit

Permalink
Merge pull request #105 from datachainlab/multiple-operators
Browse files Browse the repository at this point in the history
Multiple operators

Signed-off-by: Jun Kimura <[email protected]>
  • Loading branch information
bluele authored Jun 18, 2024
2 parents 16fa999 + 6220d89 commit 8934493
Show file tree
Hide file tree
Showing 34 changed files with 806 additions and 218 deletions.
6 changes: 6 additions & 0 deletions Cargo.lock

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

52 changes: 50 additions & 2 deletions app/src/commands/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use clap::Parser;
use crypto::Address;
use ecall_commands::IASRemoteAttestationInput;
use enclave_api::{Enclave, EnclaveCommandAPI, EnclaveProtoAPI};
use log::info;
use store::transaction::CommitStore;

/// `attestation` subcommand
Expand Down Expand Up @@ -63,6 +64,22 @@ 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>,
}

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>(
Expand All @@ -74,10 +91,18 @@ fn run_ias_remote_attestation<E: EnclaveCommandAPI<S>, S: CommitStore>(
let target_enclave_key = Address::from_hex_string(&cmd.enclave_key)?;
match enclave.ias_remote_attestation(IASRemoteAttestationInput {
target_enclave_key,
operator: cmd.get_operator()?,
spid: spid.as_bytes().to_vec(),
ias_key: ias_key.as_bytes().to_vec(),
}) {
Ok(_) => Ok(()),
Ok(res) => {
info!("AVR: {:?}", res.report.avr);
info!(
"report_data: {}",
res.report.get_avr()?.parse_quote()?.report_data()
);
Ok(())
}
Err(e) => bail!("failed to perform IAS Remote Attestation: {:?}!", e),
}
}
Expand All @@ -96,6 +121,13 @@ pub struct SimulateRemoteAttestation {
)]
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>,

/// Path to a der-encoded file that contains X.509 certificate
#[clap(
long = "signing_cert_path",
Expand Down Expand Up @@ -135,6 +167,17 @@ 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 @@ -187,13 +230,18 @@ fn run_simulate_remote_attestation<E: EnclaveCommandAPI<S>, S: CommitStore>(
match enclave.simulate_remote_attestation(
ecall_commands::SimulateRemoteAttestationInput {
target_enclave_key,
operator: cmd.get_operator()?,
advisory_ids: cmd.advisory_ids.clone(),
isv_enclave_quote_status: cmd.isv_enclave_quote_status.clone(),
},
signing_key,
signing_cert,
) {
Ok(_) => Ok(()),
Ok(res) => {
info!("AVR: {:?}", res.avr);
info!("report_data: {}", res.avr.parse_quote()?.report_data());
Ok(())
}
Err(e) => bail!("failed to simulate Remote Attestation: {:?}!", e),
}
}
2 changes: 2 additions & 0 deletions app/src/commands/enclave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@ fn run_list_keys<E: EnclaveCommandAPI<S>, S: CommitStore>(
match eki.avr {
Some(eavr) => {
let avr = eavr.get_avr()?;
let report_data = avr.parse_quote()?.report_data();
list_json.push(json! {{
"address": eki.address.to_hex_string(),
"attested": true,
"report_data": report_data.to_string(),
"isv_enclave_quote_status": avr.isv_enclave_quote_status,
"advisory_ids": avr.advisory_ids,
"attested_at": avr.timestamp
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::enclave_manage::errors::Error;
use crate::prelude::*;
use attestation_report::verify_report;
use attestation_report::{verify_report, ReportData};
use crypto::{EnclaveKey, SealingKey};
use ecall_commands::{CommandContext, IASRemoteAttestationInput, IASRemoteAttestationResponse};
use enclave_remote_attestation::{
Expand All @@ -18,7 +18,7 @@ pub(crate) fn ias_remote_attestation(
let report = {
let spid = decode_spid(&input.spid);
let report = create_attestation_report(
pub_key.as_report_data(),
ReportData::new(pub_key.as_address(), input.operator).into(),
sgx_quote_sign_type_t::SGX_UNLINKABLE_SIGNATURE,
spid,
&input.ias_key,
Expand All @@ -39,7 +39,7 @@ pub(crate) fn simulate_remote_attestation(
let pub_key =
EnclaveKey::unseal(&cctx.sealed_ek.ok_or(Error::enclave_key_not_found())?)?.get_pubkey();
let avr = enclave_remote_attestation::simulate::create_attestation_report(
pub_key.as_report_data(),
ReportData::new(pub_key.as_address(), input.operator).into(),
sgx_quote_sign_type_t::SGX_UNLINKABLE_SIGNATURE,
input.advisory_ids,
input.isv_enclave_quote_status,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub fn aggregate_messages<R: LightClientResolver, S: KVStore, K: Signer>(
.collect::<Result<Vec<_>, _>>()?;

let message = ProxyMessage::from(commitments::aggregate_messages(messages)?);
let proof = prove_commitment(ek, input.signer, message)?;
let proof = prove_commitment(ek, message)?;

Ok(LightClientResponse::AggregateMessages(
AggregateMessagesResponse(proof),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn init_client<R: LightClientResolver, S: KVStore, K: Signer>(
ctx.store_any_consensus_state(client_id.clone(), res.height, any_consensus_state)?;

let proof = if res.prove {
prove_commitment(ek, input.signer, res.message)?
prove_commitment(ek, res.message)?
} else {
CommitmentProof::new_with_no_signature(res.message.to_bytes())
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub fn update_client<R: LightClientResolver, S: KVStore, K: Signer>(
)?;

let proof = if data.prove {
prove_commitment(ek, input.signer, message)?
prove_commitment(ek, message)?
} else {
CommitmentProof::new_with_no_signature(message.to_bytes())
};
Expand All @@ -45,7 +45,7 @@ pub fn update_client<R: LightClientResolver, S: KVStore, K: Signer>(
UpdateClientResult::Misbehaviour(data) => {
ctx.store_any_client_state(input.client_id, data.new_any_client_state)?;

let proof = prove_commitment(ek, input.signer, data.message.into())?;
let proof = prove_commitment(ek, data.message.into())?;
Ok(LightClientResponse::UpdateClient(UpdateClientResponse(
proof,
)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn verify_membership<R: LightClientResolver, S: KVStore, K: Signer>(
)?;

Ok(LightClientResponse::VerifyMembership(
VerifyMembershipResponse(prove_commitment(ek, input.signer, res.message.into())?),
VerifyMembershipResponse(prove_commitment(ek, res.message.into())?),
))
}

Expand All @@ -49,6 +49,6 @@ pub fn verify_non_membership<R: LightClientResolver, S: KVStore, K: Signer>(
)?;

Ok(LightClientResponse::VerifyNonMembership(
VerifyNonMembershipResponse(prove_commitment(ek, input.signer, res.message.into())?),
VerifyNonMembershipResponse(prove_commitment(ek, res.message.into())?),
))
}
3 changes: 1 addition & 2 deletions enclave-modules/remote-attestation/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ use sgx_tstd::{
net::TcpStream,
sync::Arc,
};
use sgx_types::{c_int, sgx_spid_t};
use sgx_types::{sgx_quote_nonce_t, sgx_quote_sign_type_t, sgx_report_data_t};
use sgx_types::{c_int, sgx_quote_nonce_t, sgx_quote_sign_type_t, sgx_report_data_t, sgx_spid_t};

pub const REPORT_DATA_SIZE: usize = 32;

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.

1 change: 1 addition & 0 deletions modules/attestation-report/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
crypto = { path = "../crypto", default-features = false }
lcp-types = { path = "../types", default-features = false }
flex-error = { version = "0.4.4", default-features = false }
hex = { version = "0.4", default-features = false, features = ["alloc"] }
base64 = { git = "https://github.com/marshallpierce/rust-base64", default-features = false, features = ["alloc"] }

pem = { version = "2.0", default-features = false }
Expand Down
9 changes: 9 additions & 0 deletions modules/attestation-report/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ define_error! {
format_args!("unexpected attestation report version: expected={} actual={}", e.expected, e.actual)
},

UnexpectedReportDataVersion
{
expected: u8,
actual: u8
}
|e| {
format_args!("unexpected report data version: expected={} actual={}", e.expected, e.actual)
},

InvalidReportDataSize
{
size: usize
Expand Down
4 changes: 3 additions & 1 deletion modules/attestation-report/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ mod prelude {
pub use errors::Error;
mod errors;

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

#[cfg(any(feature = "std", feature = "sgx"))]
Expand Down
78 changes: 68 additions & 10 deletions modules/attestation-report/src/report.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,76 @@
use crate::errors::Error;
use crate::prelude::*;
use chrono::prelude::DateTime;
use core::fmt::Debug;
use core::fmt::{Debug, Display, Error as FmtError};
use crypto::Address;
use lcp_types::Time;
use serde::{Deserialize, Serialize};
use sgx_types::{metadata::metadata_t, sgx_measurement_t, sgx_quote_t};
use sgx_types::{metadata::metadata_t, sgx_measurement_t, sgx_quote_t, sgx_report_data_t};
use tendermint::Time as TmTime;

pub const REPORT_DATA_V1: u8 = 1;

/// ReportData is a 64-byte value that is embedded in the Quote
/// | version: 1 byte | enclave key: 20 bytes | operator: 20 bytes | nonce: 22 bytes |
#[derive(Debug, Clone, PartialEq)]
pub struct ReportData([u8; 64]);

impl ReportData {
pub fn new(ek: Address, operator: Option<Address>) -> Self {
let mut data: ReportData = Default::default();
data.0[0] = REPORT_DATA_V1;
data.0[1..21].copy_from_slice(ek.0.as_ref());
if let Some(operator) = operator {
data.0[21..41].copy_from_slice(operator.0.as_ref());
}
data
}

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()
}

pub fn operator(&self) -> Address {
// Unwrap is safe because the size of the slice is 20
Address::try_from(&self.0[21..41]).unwrap()
}

pub fn validate(&self) -> Result<(), Error> {
if self.0[0] != REPORT_DATA_V1 {
return Err(Error::unexpected_report_data_version(
REPORT_DATA_V1,
self.0[0],
));
}
Ok(())
}
}

impl Default for ReportData {
fn default() -> Self {
ReportData([0; 64])
}
}

impl Display for ReportData {
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), FmtError> {
write!(f, "0x{}", hex::encode(self.0))
}
}

impl From<ReportData> for sgx_report_data_t {
fn from(data: ReportData) -> Self {
sgx_report_data_t { d: data.0 }
}
}

impl From<sgx_report_data_t> for ReportData {
fn from(data: sgx_report_data_t) -> Self {
ReportData(data.d)
}
}

/// AttestationReport can be endorsed by either the Intel Attestation Service
/// using EPID or Data Center Attestation
/// Service (platform dependent) using ECDSA.
Expand All @@ -25,7 +88,7 @@ pub struct EndorsedAttestationVerificationReport {

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

Expand Down Expand Up @@ -119,13 +182,8 @@ pub struct Quote {
}

impl Quote {
pub fn get_enclave_key_address(&self) -> Result<Address, Error> {
let data = self.raw.report_body.report_data.d;
if data.len() < 20 {
Err(Error::invalid_report_data_size(data.len()))
} else {
Ok(Address::try_from(&data[..20])?)
}
pub fn report_data(&self) -> ReportData {
self.raw.report_body.report_data.into()
}

pub fn get_mrenclave(&self) -> sgx_measurement_t {
Expand Down
2 changes: 1 addition & 1 deletion modules/attestation-report/src/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub fn verify_report(
report_cert
.verify_signature(
&webpki::RSA_PKCS1_2048_8192_SHA256,
report.avr.as_bytes(),
report.avr.as_ref(),
&report.signature,
)
.map_err(|e| Error::web_pki(e.to_string()))?;
Expand Down
Loading

0 comments on commit 8934493

Please sign in to comment.