Skip to content
Open
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
5 changes: 4 additions & 1 deletion remote-attestation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
sgx_types = "1.1.1"
sgx_tse = "1.1.1"
sgx_tstd = { rev = "v1.1.2", git = "https://github.com/apache/teaclave-sgx-sdk.git", features = ["net"] }
anyhow = { rev = "sgx_1.1.2", git = "https://github.com/mesalock-linux/anyhow-sgx.git" }
webpki = { branch = "mesalock_sgx", git = "https://github.com/mesalock-linux/webpki" } # Specify branch name due to rustls dependency
sgx_tstd = { rev = "v1.1.2", git = "https://github.com/apache/teaclave-sgx-sdk.git", features = ["net"] }
http_req = { rev = "sgx_1.1.2", git = "https://github.com/mesalock-linux/http_req-sgx" }
serde_json = { rev = "sgx_1.1.2", git = "https://github.com/mesalock-linux/serde-json-sgx" }
serde = { git = "https://github.com/mesalock-linux/serde-sgx.git" } # Don't specify version due to serde_json dependency
base64 = { rev = "sgx_1.1.2", git = "https://github.com/mesalock-linux/rust-base64-sgx" }
rustls = { rev = "sgx_1.1.2", git = "https://github.com/mesalock-linux/rustls" }
log = { rev = "sgx_1.1.2", git = "https://github.com/mesalock-linux/log-sgx" }
hex = { rev = "sgx_1.1.2", git = "https://github.com/mesalock-linux/rust-hex-sgx" }
40 changes: 30 additions & 10 deletions remote-attestation/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
use std::{
prelude::v1::*,
net::TcpStream,
str,
time::{SystemTime, UNIX_EPOCH},
untrusted::time::SystemTimeEx,
io::{BufReader, Write},
collections::HashMap,
};
use http_req::{request::{Request, Method}, uri::Uri, response::{Headers, Response}};
use anyhow::{Result, anyhow, bail, ensure};
use serde_json::Value;
use log::debug;

pub const TEST_SUB_KEY: &str = "77e2533de0624df28dc3be3a5b9e50d9";
pub const TEST_SPID: &str = "2C149BFC94A61D306A96211AED155BE9";
use sgx_types::{sgx_report_data_t, sgx_spid_t};
use crate::quote::{sgx_init_quote, get_quote};

pub const IAS_REPORT_CA: &[u8] = include_bytes!("../AttestationReportSigningCACert.pem");
type SignatureAlgorithms = &'static [&'static webpki::SignatureAlgorithm];
Expand All @@ -32,16 +27,41 @@ static SUPPORTED_SIG_ALGS: SignatureAlgorithms = &[
];

/// The very high level service for remote attestations
pub struct RAService;
pub struct RAService {
encoded_quote: String,
}

impl RAService {
// spid: Service provider ID for the ISV.
/// Generate Base64-encoded QUOTE data structure.
/// QUOTE will be sent to Attestation Service to verify SGX's status.
/// For more information: https://api.trustedservices.intel.com/documents/sgx-attestation-api-spec.pdf
pub fn new(spid: &str, report_data: &sgx_report_data_t) -> Result<Self> {
let spid_vec = hex::decode(spid)?;
let mut id = [0; 16];
id.copy_from_slice(&spid_vec);
let spid: sgx_spid_t = sgx_spid_t { id };

let target_info = sgx_init_quote()?;
let report = sgx_tse::rsgx_create_report(&target_info, &report_data)
.map_err(|e| anyhow!("{}", e))?;
let quote = get_quote(report, &spid)?;

// Use base64-encoded QUOTE structure to communicate via defined API.
let encoded_quote = base64::encode(&quote);

Ok(RAService {
encoded_quote,
})
}

pub fn remote_attestation(
&self,
uri: &str,
ias_api_key: &str,
quote: &str,
) -> Result<(AttestationReport, ReportSig)> {
let uri: Uri = uri.parse().expect("Invalid uri");
let body = format!("{{\"isvEnclaveQuote\":\"{}\"}}\r\n", quote);
let body = format!("{{\"isvEnclaveQuote\":\"{}\"}}\r\n", &self.encoded_quote);
let mut writer = Vec::new();

let response = RAClient::new(&uri)
Expand Down
1 change: 1 addition & 0 deletions remote-attestation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
extern crate sgx_tstd as std;

mod client;
mod quote;

pub use crate::client::{RAService, AttestationReport, ReportSig};
74 changes: 74 additions & 0 deletions remote-attestation/src/quote.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use sgx_types::*;
use anyhow::{Result, ensure};
use std::vec::Vec;

extern "C" {
pub fn ocall_sgx_init_quote(
retval: *mut sgx_status_t,
ret_ti: *mut sgx_target_info_t,
ret_gid: *mut sgx_epid_group_id_t,
) -> sgx_status_t;
}
extern "C" {
pub fn ocall_get_quote(
retval: *mut sgx_status_t,
p_sigrl: *const u8,
sigrl_len: u32,
report: *const sgx_report_t,
quote_type: sgx_quote_sign_type_t,
p_spid: *const sgx_spid_t,
p_nonce: *const sgx_quote_nonce_t,
p_qe_report: *mut sgx_report_t,
p_quote: *mut sgx_quote_t,
maxlen: u32,
p_quote_len: *mut u32,
) -> sgx_status_t;
}

pub fn sgx_init_quote() -> Result<sgx_target_info_t> {
let mut rt = sgx_status_t::SGX_ERROR_UNEXPECTED;
let mut target_info = sgx_target_info_t::default();
let mut gid = sgx_epid_group_id_t::default();

let status = unsafe {
ocall_sgx_init_quote(
&mut rt as *mut sgx_status_t,
&mut target_info as *mut sgx_target_info_t,
&mut gid as *mut sgx_epid_group_id_t,
)
};

ensure!(status == sgx_status_t::SGX_SUCCESS, "Ocall Error ocall_sgx_init_quote: {:?}", status);
ensure!(rt == sgx_status_t::SGX_SUCCESS, "Init Quote Error: {:?}", status);

Ok(target_info)
}

pub fn get_quote(report: sgx_report_t, spid: &sgx_spid_t) -> Result<Vec<u8>> {
const RET_QUOTE_BUF_LEN : u32 = 2048;
let mut quote_len: u32 = 0;
let mut rt = sgx_status_t::SGX_ERROR_UNEXPECTED;
let mut quote = vec![0u8; RET_QUOTE_BUF_LEN as usize];

let status = unsafe {
ocall_get_quote(
&mut rt as *mut sgx_status_t,
std::ptr::null(), // p_sigrl
0, // sigrl_len
&report as *const sgx_report_t,
sgx_quote_sign_type_t::SGX_UNLINKABLE_SIGNATURE, // quote_type
spid as *const sgx_spid_t, // p_spid
std::ptr::null(), // p_nonce
std::ptr::null_mut(), // p_qe_report
quote.as_mut_ptr() as *mut sgx_quote_t,
RET_QUOTE_BUF_LEN, // maxlen
&mut quote_len as *mut u32,
)
};

ensure!(status == sgx_status_t::SGX_SUCCESS, "Ocall Error ocall_get_quote: {:?}", status);
ensure!(rt == sgx_status_t::SGX_SUCCESS, "Get Quote Error: {:?}", status);

let _ = quote.split_off(quote_len as usize);
Ok(quote)
}