Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 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
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
126 changes: 86 additions & 40 deletions core-primitives/sgx/crypto/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,104 @@

*/

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::*;

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 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 +121,14 @@ pub mod sgx {
type Unsealed = ed25519::Pair;

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

fn seal(&self, unsealed: &Self::Unsealed) -> Result<()> {
Self::seal_to_static_file(unsealed)
ed25519::Pair::from_seed_slice(&raw)
.map_err(|e| Error::Other(format!("{:?}", e).into()))
}
}

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

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

Ok(seal(&seed, SEALED_SIGNER_SEED_FILE)?)
}
}
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
13 changes: 10 additions & 3 deletions enclave-runtime/src/initialization/global_components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ use itp_node_api::{
metadata::{provider::NodeMetadataRepository, NodeMetadata},
};
use itp_nonce_cache::NonceCache;
use itp_sgx_crypto::{key_repository::KeyRepository, Aes, AesSeal, Rsa3072Seal};
use itp_sgx_crypto::{key_repository::KeyRepository, Aes, AesSeal, Ed25519Seal, Rsa3072Seal};
use itp_stf_executor::{
enclave_signer::StfEnclaveSigner, executor::StfExecutor, getter_executor::GetterExecutor,
state_getter::StfStateGetter,
Expand Down Expand Up @@ -90,7 +90,7 @@ use its_sidechain::{
};
use sgx_crypto_helper::rsa3072::Rsa3072KeyPair;
use sgx_tstd::vec::Vec;
use sp_core::ed25519::Pair;
use sp_core::{ed25519, ed25519::Pair};

pub type EnclaveParentchainSigner =
itp_node_api::api_client::StaticExtrinsicSigner<Pair, PairSignature>;
Expand All @@ -100,6 +100,7 @@ pub type EnclaveTrustedCallSigned = TrustedCallSigned;
pub type EnclaveStf = Stf<EnclaveTrustedCallSigned, EnclaveGetter, StfState, Runtime>;
pub type EnclaveStateKeyRepository = KeyRepository<Aes, AesSeal>;
pub type EnclaveShieldingKeyRepository = KeyRepository<Rsa3072KeyPair, Rsa3072Seal>;
pub type EnclaveSigningKeyRepository = KeyRepository<ed25519::Pair, Ed25519Seal>;
pub type EnclaveStateFileIo = SgxStateFileIo<EnclaveStateKeyRepository, StfState>;
pub type EnclaveStateSnapshotRepository = StateSnapshotRepository<EnclaveStateFileIo>;
pub type EnclaveStateObserver = StateObserver<StfState>;
Expand All @@ -119,7 +120,8 @@ pub type EnclaveStfEnclaveSigner = StfEnclaveSigner<
EnclaveStf,
EnclaveTopPoolAuthor,
>;
pub type EnclaveAttestationHandler = IntelAttestationHandler<EnclaveOCallApi>;
pub type EnclaveAttestationHandler =
IntelAttestationHandler<EnclaveOCallApi, EnclaveSigningKeyRepository>;

pub type EnclaveRpcConnectionRegistry = ConnectionRegistry<Hash, ConnectionToken>;
pub type EnclaveRpcWsHandler =
Expand Down Expand Up @@ -237,6 +239,11 @@ pub static GLOBAL_SHIELDING_KEY_REPOSITORY_COMPONENT: ComponentContainer<
EnclaveShieldingKeyRepository,
> = ComponentContainer::new("Shielding key repository");

/// Signing key repository
pub static GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT: ComponentContainer<
EnclaveSigningKeyRepository,
> = ComponentContainer::new("Signing key repository");

/// O-Call API
pub static GLOBAL_OCALL_API_COMPONENT: ComponentContainer<EnclaveOCallApi> =
ComponentContainer::new("O-call API");
Expand Down
27 changes: 15 additions & 12 deletions enclave-runtime/src/initialization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ use crate::{
GLOBAL_RPC_WS_HANDLER_COMPONENT, GLOBAL_SHIELDING_KEY_REPOSITORY_COMPONENT,
GLOBAL_SIDECHAIN_BLOCK_COMPOSER_COMPONENT, GLOBAL_SIDECHAIN_BLOCK_SYNCER_COMPONENT,
GLOBAL_SIDECHAIN_IMPORT_QUEUE_COMPONENT, GLOBAL_SIDECHAIN_IMPORT_QUEUE_WORKER_COMPONENT,
GLOBAL_STATE_HANDLER_COMPONENT, GLOBAL_STATE_KEY_REPOSITORY_COMPONENT,
GLOBAL_STATE_OBSERVER_COMPONENT, GLOBAL_TOP_POOL_AUTHOR_COMPONENT,
GLOBAL_WEB_SOCKET_SERVER_COMPONENT,
GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT,
GLOBAL_STATE_KEY_REPOSITORY_COMPONENT, GLOBAL_STATE_OBSERVER_COMPONENT,
GLOBAL_TOP_POOL_AUTHOR_COMPONENT, GLOBAL_WEB_SOCKET_SERVER_COMPONENT,
},
ocall::OcallApi,
rpc::{rpc_response_channel::RpcResponseChannel, worker_api_direct::public_api_rpc_handler},
Expand All @@ -60,7 +60,9 @@ use itp_attestation_handler::IntelAttestationHandler;
use itp_component_container::{ComponentGetter, ComponentInitializer};
use itp_primitives_cache::GLOBAL_PRIMITIVES_CACHE;
use itp_settings::files::STATE_SNAPSHOTS_CACHE_SIZE;
use itp_sgx_crypto::{aes, ed25519, get_rsa3072_repository, AesSeal, Ed25519Seal};
use itp_sgx_crypto::{
aes, get_ed25519_repository, get_rsa3072_repository, key_repository::AccessKey, AesSeal,
};
use itp_sgx_io::StaticSealedIO;
use itp_stf_state_handler::{
handle_state::HandleState, query_shard_state::QueryShardState,
Expand All @@ -80,8 +82,9 @@ pub(crate) fn init_enclave(
untrusted_worker_url: String,
base_dir: PathBuf,
) -> EnclaveResult<()> {
ed25519::create_sealed_if_absent().map_err(Error::Crypto)?;
let signer = Ed25519Seal::unseal_from_static_file().map_err(Error::Crypto)?;
let signing_key_repository = Arc::new(get_ed25519_repository(base_dir.clone())?);
GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT.initialize(signing_key_repository.clone());
let signer = signing_key_repository.retrieve_key()?;
info!("[Enclave initialized] Ed25519 prim raw : {:?}", signer.public().0);

let shielding_key_repository = Arc::new(get_rsa3072_repository(base_dir)?);
Expand Down Expand Up @@ -162,7 +165,8 @@ pub(crate) fn init_enclave(
let sidechain_block_import_queue = Arc::new(EnclaveSidechainBlockImportQueue::default());
GLOBAL_SIDECHAIN_IMPORT_QUEUE_COMPONENT.initialize(sidechain_block_import_queue);

let attestation_handler = Arc::new(IntelAttestationHandler::new(ocall_api));
let attestation_handler =
Arc::new(IntelAttestationHandler::new(ocall_api, signing_key_repository));
GLOBAL_ATTESTATION_HANDLER_COMPONENT.initialize(attestation_handler);

Ok(())
Expand All @@ -187,12 +191,11 @@ pub(crate) fn init_enclave_sidechain_components() -> EnclaveResult<()> {
let state_handler = GLOBAL_STATE_HANDLER_COMPONENT.get()?;
let ocall_api = GLOBAL_OCALL_API_COMPONENT.get()?;
let top_pool_author = GLOBAL_TOP_POOL_AUTHOR_COMPONENT.get()?;
let state_key_repository = GLOBAL_STATE_KEY_REPOSITORY_COMPONENT.get()?;

let parentchain_block_import_dispatcher = get_triggered_dispatcher_from_solo_or_parachain()?;

let state_key_repository = GLOBAL_STATE_KEY_REPOSITORY_COMPONENT.get()?;

let signer = Ed25519Seal::unseal_from_static_file()?;
let signer = GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT.get()?.retrieve_key()?;

let sidechain_block_importer = Arc::new(EnclaveSidechainBlockImporter::new(
state_handler,
Expand Down Expand Up @@ -236,10 +239,10 @@ pub(crate) fn init_enclave_sidechain_components() -> EnclaveResult<()> {

pub(crate) fn init_direct_invocation_server(server_addr: String) -> EnclaveResult<()> {
let rpc_handler = GLOBAL_RPC_WS_HANDLER_COMPONENT.get()?;
let signing = Ed25519Seal::unseal_from_static_file()?;
let signer = GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT.get()?.retrieve_key()?;

let cert =
ed25519_self_signed_certificate(signing, "Enclave").map_err(|e| Error::Other(e.into()))?;
ed25519_self_signed_certificate(signer, "Enclave").map_err(|e| Error::Other(e.into()))?;

// Serialize certificate(s) and private key to PEM.
// PEM format is needed as a certificate chain can only be serialized into PEM.
Expand Down
9 changes: 4 additions & 5 deletions enclave-runtime/src/initialization/parentchain/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,15 @@ use crate::{
EnclaveParentchainEventImportQueue, EnclaveParentchainSigner, EnclaveStfExecutor,
EnclaveTriggeredParentchainBlockImportDispatcher, EnclaveValidatorAccessor,
GLOBAL_OCALL_API_COMPONENT, GLOBAL_SHIELDING_KEY_REPOSITORY_COMPONENT,
GLOBAL_STATE_HANDLER_COMPONENT, GLOBAL_STATE_OBSERVER_COMPONENT,
GLOBAL_TOP_POOL_AUTHOR_COMPONENT,
GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT, GLOBAL_STATE_HANDLER_COMPONENT,
GLOBAL_STATE_OBSERVER_COMPONENT, GLOBAL_TOP_POOL_AUTHOR_COMPONENT,
},
EnclaveStfEnclaveSigner,
},
};
use itp_component_container::ComponentGetter;
use itp_nonce_cache::GLOBAL_NONCE_CACHE;
use itp_sgx_crypto::Ed25519Seal;
use itp_sgx_io::StaticSealedIO;
use itp_sgx_crypto::key_repository::AccessKey;
use log::*;
use sp_core::H256;
use std::sync::Arc;
Expand Down Expand Up @@ -75,7 +74,7 @@ pub(crate) fn create_extrinsics_factory(
genesis_hash: H256,
node_metadata_repository: Arc<EnclaveNodeMetadataRepository>,
) -> Result<Arc<EnclaveExtrinsicsFactory>> {
let signer = Ed25519Seal::unseal_from_static_file()?;
let signer = GLOBAL_SIGNING_KEY_REPOSITORY_COMPONENT.get()?.retrieve_key()?;

Ok(Arc::new(EnclaveExtrinsicsFactory::new(
genesis_hash,
Expand Down
Loading