Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8550d7d
[itp-sgx-crypto] add `ToPubkey` and `AccessPubkey` traits
clangenb May 23, 2023
560c787
[itp-sgx-crypto] refactor the Rsa3072 stuff to no longer use static f…
clangenb May 23, 2023
2906f8f
[itp-sgx-crypto] set-base-path to the PWD
clangenb May 23, 2023
e9dbe6e
[enclave-runtime] more explanation about using the PWD
clangenb May 23, 2023
177503d
[enclave-runtime] add todo for replacing the once-cell.
clangenb May 23, 2023
5645420
taplo fmt
clangenb May 23, 2023
0c1d6b9
add some doc
clangenb May 23, 2023
8ea4fff
typo
clangenb May 23, 2023
b229b3e
Merge branch 'master' into cl/set-base-path-of-shielding-key
clangenb May 23, 2023
7a381e4
[sgx-crypto] log full path instead of just filename.
clangenb May 24, 2023
33faf7d
[itp-sgx-io] fix standalone compilation
clangenb May 24, 2023
19b873e
[itp-sgx-crypto] put some functions behind a trait.
clangenb May 24, 2023
b5c5284
[enclave-runtime/attestation_handler] add signing key repo to struct
clangenb May 24, 2023
6a71619
[itp-sgx-crypto] impl `ToPubkey` for `ed25511::Pair`
clangenb May 24, 2023
cc0be6e
introduce `SigningKeyRepository` and remove all instances of `StaticF…
clangenb May 24, 2023
16be63e
Merge branch 'master' into cl/set-base-path-of-signing-key
clangenb May 24, 2023
eac6869
[itp-sgx-crypto] change `exists()` implementations to use `self.path(…
clangenb May 24, 2023
9b51633
[itp-sgx-crypto] fix clippy warnings
clangenb May 24, 2023
6fddceb
taplo fmt
clangenb May 24, 2023
c856a8f
[itp-sgx-crypto] add tests for ed25519 module.
clangenb May 25, 2023
14d2059
[itp-sgx-crypto] add tests for rsa3072 module.
clangenb May 25, 2023
dccc7e6
[itp-sgx-crypto] move seed file constant from settings to the ed25519…
clangenb May 25, 2023
97a2397
typo
clangenb May 25, 2023
7ed1d63
[itp-sgx-crypto] tests: ensure that the keys don't exist initially
clangenb May 25, 2023
261e3ff
Merge branch 'master' into cl/set-base-path-of-signing-key
clangenb May 25, 2023
ee0ab63
[itp-sgx-crypto] tests: fix tempdir prefixes.
clangenb May 25, 2023
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3514,6 +3514,7 @@ dependencies = [
"derive_more",
"itp-settings",
"itp-sgx-io",
"itp-sgx-temp-dir",
"log 0.4.17",
"ofb",
"parity-scale-codec",
Expand Down
29 changes: 17 additions & 12 deletions core-primitives/attestation-handler/src/attestation_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ use itp_settings::{
files::{RA_API_KEY_FILE, RA_DUMP_CERT_DER_FILE, RA_SPID_FILE},
worker::MR_ENCLAVE_SIZE,
};
use itp_sgx_crypto::Ed25519Seal;
use itp_sgx_crypto::key_repository::AccessKey;
use itp_sgx_io as io;
use itp_sgx_io::StaticSealedIO;
use itp_time_utils::now_as_secs;
use log::*;
use sgx_rand::{os, Rng};
Expand All @@ -51,7 +50,7 @@ use sgx_types::{
c_int, sgx_epid_group_id_t, sgx_quote_nonce_t, sgx_quote_sign_type_t, sgx_report_data_t,
sgx_spid_t, sgx_status_t, sgx_target_info_t, SgxResult, *,
};
use sp_core::Pair;
use sp_core::{ed25519, Pair};
use std::{
borrow::ToOwned,
env, format,
Expand Down Expand Up @@ -115,13 +114,16 @@ pub trait AttestationHandler {
) -> EnclaveResult<(Vec<u8>, Vec<u8>)>;
}

pub struct IntelAttestationHandler<OCallApi> {
pub struct IntelAttestationHandler<OCallApi, SigningKeyRepo> {
pub(crate) ocall_api: Arc<OCallApi>,
pub(crate) signing_key_repo: Arc<SigningKeyRepo>,
}

impl<OCallApi> AttestationHandler for IntelAttestationHandler<OCallApi>
impl<OCallApi, AccessSigningKey> AttestationHandler
for IntelAttestationHandler<OCallApi, AccessSigningKey>
where
OCallApi: EnclaveAttestationOCallApi,
AccessSigningKey: AccessKey<KeyType = ed25519::Pair>,
{
fn generate_ias_ra_cert(&self, skip_ra: bool) -> EnclaveResult<Vec<u8>> {
// Our certificate is unlinkable.
Expand Down Expand Up @@ -195,7 +197,7 @@ where
sign_type: sgx_quote_sign_type_t,
skip_ra: bool,
) -> EnclaveResult<(Vec<u8>, Vec<u8>)> {
let chain_signer = Ed25519Seal::unseal_from_static_file()?;
let chain_signer = self.signing_key_repo.retrieve_key()?;
info!("[Enclave Attestation] Ed25519 pub raw : {:?}", chain_signer.public().0);

info!(" [Enclave] Generate keypair");
Expand Down Expand Up @@ -249,7 +251,7 @@ where
quote_size: u32,
skip_ra: bool,
) -> EnclaveResult<(Vec<u8>, Vec<u8>)> {
let chain_signer = Ed25519Seal::unseal_from_static_file()?;
let chain_signer = self.signing_key_repo.retrieve_key()?;
info!("[Enclave Attestation] Ed25519 signer pub key: {:?}", chain_signer.public().0);

let ecc_handle = SgxEccHandle::new();
Expand Down Expand Up @@ -291,14 +293,17 @@ where
}
}

impl<OCallApi> IntelAttestationHandler<OCallApi>
impl<OCallApi, AccessSigningKey> IntelAttestationHandler<OCallApi, AccessSigningKey> {
pub fn new(ocall_api: Arc<OCallApi>, signing_key_repo: Arc<AccessSigningKey>) -> Self {
Self { ocall_api, signing_key_repo }
}
}

impl<OCallApi, AccessSigningKey> IntelAttestationHandler<OCallApi, AccessSigningKey>
where
OCallApi: EnclaveAttestationOCallApi,
AccessSigningKey: AccessKey<KeyType = ed25519::Pair>,
{
pub fn new(ocall_api: Arc<OCallApi>) -> Self {
Self { ocall_api }
}

fn parse_response_attn_report(&self, resp: &[u8]) -> EnclaveResult<(String, String, String)> {
debug!(" [Enclave] Entering parse_response_attn_report");
let mut headers = [httparse::EMPTY_HEADER; 16];
Expand Down
1 change: 0 additions & 1 deletion core-primitives/settings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ pub mod files {
pub static SIDECHAIN_PURGE_LIMIT: u64 = 100; // keep the last.. sidechainblocks when purging

// used by enclave
pub const SEALED_SIGNER_SEED_FILE: &str = "ed25519_key_sealed.bin";
pub const AES_KEY_FILE_AND_INIT_V: &str = "aes_key_sealed.bin";
pub const LIGHT_CLIENT_DB: &str = "light_client_db.bin";

Expand Down
10 changes: 10 additions & 0 deletions core-primitives/sgx/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ sp-core = { default-features = false, git = "https://github.com/paritytech/subst
itp-settings = { path = "../../settings" }
itp-sgx-io = { path = "../io", default-features = false }

# test sgx deps
itp-sgx-temp-dir = { default-features = false, optional = true, path = "../temp-dir" }

[features]
default = ["std"]
std = [
Expand All @@ -49,3 +52,10 @@ sgx = [
"serde-sgx",
]
mocks = []
test = [
# features
"mocks",
"sgx",
# deps
"itp-sgx-temp-dir",
]
164 changes: 128 additions & 36 deletions core-primitives/sgx/crypto/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,107 @@

*/

use derive_more::Display;

#[derive(Copy, Clone, Debug, Display)]
pub struct Ed25519Seal;
use crate::{
error::{Error, Result},
ToPubkey,
};
use sp_core::ed25519;

#[cfg(feature = "sgx")]
pub use sgx::*;

/// File name of the sealed Ed25519 seed file.
pub const SEALED_SIGNER_SEED_FILE: &str = "ed25519_key_sealed.bin";

pub trait Ed25519Sealing {
fn unseal_pubkey(&self) -> Result<ed25519::Public>;

fn unseal_pair(&self) -> Result<ed25519::Pair>;

fn exists(&self) -> bool;

fn create_sealed_if_absent(&self) -> Result<()>;

fn create_sealed(&self) -> Result<()>;
}

impl ToPubkey for ed25519::Pair {
type Error = Error;
type Pubkey = ed25519::Public;

fn pubkey(&self) -> Result<Self::Pubkey> {
Ok((*self).into())
}
}

#[cfg(feature = "sgx")]
pub mod sgx {

use super::*;
use crate::error::{Error, Result};
use super::SEALED_SIGNER_SEED_FILE;
use crate::{
error::{Error, Result},
key_repository::KeyRepository,
Ed25519Sealing,
};
use codec::Encode;
use itp_settings::files::SEALED_SIGNER_SEED_FILE;
use itp_sgx_io::{seal, unseal, SealedIO, StaticSealedIO};
use itp_sgx_io::{seal, unseal, SealedIO};
use log::*;
use sgx_rand::{Rng, StdRng};
use sp_core::{crypto::Pair, ed25519};
use std::{path::Path, sgxfs::SgxFile};
use std::path::PathBuf;

/// Gets a repository for an Ed25519 keypair and initializes
/// a fresh key pair if it doesn't exist at `path`.
pub fn get_ed25519_repository(
path: PathBuf,
) -> Result<KeyRepository<ed25519::Pair, Ed25519Seal>> {
let ed25519_seal = Ed25519Seal::new(path);
ed25519_seal.create_sealed_if_absent()?;
let signing_pair = ed25519_seal.unseal_pair()?;
Ok(KeyRepository::new(signing_pair, ed25519_seal.into()))
}

impl StaticSealedIO for Ed25519Seal {
type Error = Error;
type Unsealed = ed25519::Pair;
#[derive(Clone, Debug)]
pub struct Ed25519Seal {
base_path: PathBuf,
}

fn unseal_from_static_file() -> Result<ed25519::Pair> {
let raw = unseal(SEALED_SIGNER_SEED_FILE)?;
impl Ed25519Seal {
pub fn new(base_path: PathBuf) -> Self {
Self { base_path }
}

let key = ed25519::Pair::from_seed_slice(&raw)
.map_err(|e| Error::Other(format!("{:?}", e).into()))?;
pub fn path(&self) -> PathBuf {
self.base_path.join(SEALED_SIGNER_SEED_FILE)
}
}

impl Ed25519Sealing for Ed25519Seal {
fn unseal_pubkey(&self) -> Result<ed25519::Public> {
self.unseal().map(Into::into)
}

fn unseal_pair(&self) -> Result<ed25519::Pair> {
self.unseal()
}

Ok(key.into())
fn exists(&self) -> bool {
self.path().exists()
}

fn seal_to_static_file(unsealed: &Self::Unsealed) -> Result<()> {
Ok(unsealed.seed().using_encoded(|bytes| seal(bytes, SEALED_SIGNER_SEED_FILE))?)
fn create_sealed_if_absent(&self) -> Result<()> {
if !self.exists() {
info!("Keyfile not found, creating new! {}", self.path().display());
return self.create_sealed()
}
Ok(())
}

fn create_sealed(&self) -> Result<()> {
let mut seed = [0u8; 32];
let mut rand = StdRng::new()?;
rand.fill_bytes(&mut seed);

Ok(seal(&seed, self.path())?)
}
}

Expand All @@ -59,30 +124,57 @@ pub mod sgx {
type Unsealed = ed25519::Pair;

fn unseal(&self) -> Result<Self::Unsealed> {
Self::unseal_from_static_file()
let raw = unseal(self.path())?;

ed25519::Pair::from_seed_slice(&raw)
.map_err(|e| Error::Other(format!("{:?}", e).into()))
}

fn seal(&self, unsealed: &Self::Unsealed) -> Result<()> {
Self::seal_to_static_file(unsealed)
Ok(unsealed.seed().using_encoded(|bytes| seal(bytes, self.path()))?)
}
}
}

pub fn create_sealed_if_absent() -> Result<()> {
if SgxFile::open(SEALED_SIGNER_SEED_FILE).is_err() {
if Path::new(SEALED_SIGNER_SEED_FILE).exists() {
panic!("[Enclave] Keyfile {} exists but can't be opened. has it been written by the same enclave?", SEALED_SIGNER_SEED_FILE);
}
info!("[Enclave] Keyfile not found, creating new! {}", SEALED_SIGNER_SEED_FILE);
return create_sealed_seed()
}
Ok(())
#[cfg(feature = "test")]
pub mod sgx_tests {
use super::sgx::*;
use crate::{key_repository::AccessKey, Ed25519Sealing, ToPubkey};
use itp_sgx_temp_dir::TempDir;

pub fn using_get_ed25519_repository_twice_initializes_key_only_once() {
let temp_dir =
TempDir::with_prefix("using_get_rsa3072_repository_twice_initializes_key_only_once")
.unwrap();
let temp_path = temp_dir.path().to_path_buf();
let key1 = get_ed25519_repository(temp_path.clone()).unwrap().retrieve_key().unwrap();
let key2 = get_ed25519_repository(temp_path).unwrap().retrieve_key().unwrap();
assert_eq!(key1.pubkey().unwrap(), key2.pubkey().unwrap());
}

pub fn create_sealed_seed() -> Result<()> {
let mut seed = [0u8; 32];
let mut rand = StdRng::new()?;
rand.fill_bytes(&mut seed);
pub fn ed25529_sealing_works() {
let temp_dir = TempDir::with_prefix("ed25529_sealing_works").unwrap();
let seal = Ed25519Seal::new(temp_dir.path().to_path_buf());

// Create new sealed keys and unseal them.
assert!(!seal.exists());
seal.create_sealed_if_absent().unwrap();
let pair = seal.unseal_pair().unwrap();
let pubkey = seal.unseal_pubkey().unwrap();

assert!(seal.exists());
assert_eq!(pair.pubkey().unwrap(), pubkey);

// Should not change anything because the key is already there.
seal.create_sealed_if_absent().unwrap();
let pair_same = seal.unseal_pair().unwrap();

assert_eq!(pair.pubkey().unwrap(), pair_same.pubkey().unwrap());

// Should overwrite previous keys.
seal.create_sealed().unwrap();
let pair_different = seal.unseal_pair().unwrap();

Ok(seal(&seed, SEALED_SIGNER_SEED_FILE)?)
assert_ne!(pair_different.pubkey().unwrap(), pair.pubkey().unwrap());
}
}
11 changes: 11 additions & 0 deletions core-primitives/sgx/crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,14 @@ pub use traits::*;

#[cfg(feature = "mocks")]
pub mod mocks;

#[cfg(feature = "test")]
pub mod tests {
pub use super::ed25519::sgx_tests::{
ed25529_sealing_works, using_get_ed25519_repository_twice_initializes_key_only_once,
};

pub use super::rsa3072::sgx_tests::{
rsa3072_sealing_works, using_get_rsa3072_repository_twice_initializes_key_only_once,
};
}
49 changes: 49 additions & 0 deletions core-primitives/sgx/crypto/src/rsa3072.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,52 @@ pub mod sgx {
}
}
}

#[cfg(feature = "test")]
pub mod sgx_tests {
use super::{serde_json, sgx::*};
use crate::{key_repository::AccessKey, RsaSealing, ToPubkey};
use itp_sgx_temp_dir::TempDir;
use sgx_crypto_helper::rsa3072::Rsa3072PubKey;

/// Helper method because Rsa3072 does not implement `Eq`.
pub fn equal(pubkey1: &Rsa3072PubKey, pubkey2: &Rsa3072PubKey) -> bool {
serde_json::to_vec(pubkey1).unwrap() == serde_json::to_vec(pubkey2).unwrap()
}

pub fn using_get_rsa3072_repository_twice_initializes_key_only_once() {
let temp_dir =
TempDir::with_prefix("using_get_rsa3072_repository_twice_initializes_key_only_once")
.unwrap();
let temp_path = temp_dir.path().to_path_buf();
let key1 = get_rsa3072_repository(temp_path.clone()).unwrap().retrieve_key().unwrap();
let key2 = get_rsa3072_repository(temp_path).unwrap().retrieve_key().unwrap();
assert!(equal(&key1.pubkey().unwrap(), &key2.pubkey().unwrap()));
}

pub fn rsa3072_sealing_works() {
let temp_dir = TempDir::with_prefix("rsa3072_sealing_works").unwrap();
let seal = Rsa3072Seal::new(temp_dir.path().to_path_buf());

// Create new sealed keys and unseal them
assert!(!seal.exists());
seal.create_sealed_if_absent().unwrap();
let pair = seal.unseal_pair().unwrap();
let pubkey = seal.unseal_pubkey().unwrap();

assert!(seal.exists());
assert!(equal(&pair.pubkey().unwrap(), &pubkey));

// Should not change anything because the key is already there.
seal.create_sealed_if_absent().unwrap();
let pair_same = seal.unseal_pair().unwrap();

assert!(equal(&pair.pubkey().unwrap(), &pair_same.pubkey().unwrap()));

// Should overwrite previous keys.
seal.create_sealed().unwrap();
let pair_different = seal.unseal_pair().unwrap();

assert!(!equal(&pair_different.pubkey().unwrap(), &pair.pubkey().unwrap()));
}
}
2 changes: 1 addition & 1 deletion core-primitives/sgx/io/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2021"
[dependencies]

# sgx deps
sgx_tstd = { branch = "master", git = "https://github.com/apache/teaclave-sgx-sdk.git", optional = true }
sgx_tstd = { optional = true, features = ["untrusted_fs"], branch = "master", git = "https://github.com/apache/teaclave-sgx-sdk.git" }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixes standalone compilation of the crate with: cargo check -p itp-sgx-io --no-default-features --features sgx

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question regarding this: how did you find it out that itp-sgx-io no longer compiles alone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It never did, we don't test standalone compilations of crates usually. I suspect many incomplete feature flags in our crates...


[features]
default = ["std"]
Expand Down
Loading