diff --git a/.changelog/4930.internal.md b/.changelog/4930.internal.md new file mode 100644 index 00000000000..8c0c1859c5f --- /dev/null +++ b/.changelog/4930.internal.md @@ -0,0 +1 @@ +keymanager: Refactor and reorganize runtime-related crates diff --git a/Cargo.lock b/Cargo.lock index 4aa6c7682ed..3a09cf339a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1867,50 +1867,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbeffe8aae62d42a39195627a3f3741c0cb3679c0d3ebb87a724ceb4624374e0" [[package]] -name = "oasis-core-keymanager-api-common" +name = "oasis-core-keymanager" version = "0.0.0" dependencies = [ "anyhow", "base64", - "lazy_static", - "oasis-cbor", - "oasis-core-runtime", - "rand 0.7.3", - "rustc-hex", - "thiserror", - "x25519-dalek", - "zeroize", -] - -[[package]] -name = "oasis-core-keymanager-client" -version = "0.0.0" -dependencies = [ "futures 0.3.21", "io-context", - "lru", - "oasis-cbor", - "oasis-core-keymanager-api-common", - "oasis-core-runtime", - "thiserror", -] - -[[package]] -name = "oasis-core-keymanager-lib" -version = "0.0.0" -dependencies = [ - "anyhow", - "io-context", "lazy_static", "lru", "oasis-cbor", - "oasis-core-keymanager-api-common", - "oasis-core-keymanager-client", "oasis-core-runtime", "rand 0.7.3", "rustc-hex", "sgx-isa 0.3.3", "sp800-185", + "thiserror", "tiny-keccak 2.0.2", "tokio 1.20.1", "x25519-dalek", @@ -2723,8 +2695,7 @@ checksum = "f054c6c1a6e95179d6f23ed974060dcefb2d9388bb7256900badad682c499de4" name = "simple-keymanager" version = "0.0.0" dependencies = [ - "oasis-core-keymanager-api-common", - "oasis-core-keymanager-lib", + "oasis-core-keymanager", "oasis-core-runtime", "oasis-core-tools", ] @@ -2737,8 +2708,7 @@ dependencies = [ "byteorder", "io-context", "oasis-cbor", - "oasis-core-keymanager-api-common", - "oasis-core-keymanager-client", + "oasis-core-keymanager", "oasis-core-runtime", "oasis-core-tools", "simple-keymanager", diff --git a/Cargo.toml b/Cargo.toml index 4231efe3330..bb81991b07f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,9 +2,7 @@ members = [ "runtime", "runtime-loader", - "keymanager-client", - "keymanager-api-common", - "keymanager-lib", + "keymanager", "tools", # Test runtimes. diff --git a/keymanager-api-common/Cargo.toml b/keymanager-api-common/Cargo.toml deleted file mode 100644 index 566fcd28b2c..00000000000 --- a/keymanager-api-common/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "oasis-core-keymanager-api-common" -version = "0.0.0" -authors = ["Oasis Protocol Foundation "] -edition = "2018" - -[dependencies] -oasis-core-runtime = { path = "../runtime" } -cbor = { version = "0.5.0", package = "oasis-cbor" } - -base64 = "0.13.0" -rustc-hex = "2.0.1" -anyhow = "1.0" -thiserror = "1.0" -lazy_static = "1.3.0" -x25519-dalek = "1.1.0" -rand = "0.7.3" -zeroize = "1.4.2" diff --git a/keymanager-api-common/src/api.rs b/keymanager-api-common/src/api.rs deleted file mode 100644 index 13ceea8c6cf..00000000000 --- a/keymanager-api-common/src/api.rs +++ /dev/null @@ -1,418 +0,0 @@ -use std::{collections::HashSet, default::Default, vec}; - -use rand::{rngs::OsRng, Rng}; -use thiserror::Error; -use x25519_dalek; -use zeroize::Zeroize; - -use oasis_core_runtime::{ - common::{ - crypto::signature::{PublicKey as OasisPublicKey, Signature}, - namespace::Namespace, - }, - consensus::{ - beacon::EpochTime, - keymanager::{PolicySGX, SignedPolicySGX}, - }, - impl_bytes, -}; - -impl_bytes!(KeyPairId, 32, "A 256-bit key pair identifier."); -impl_bytes!(PublicKey, 32, "A public key."); - -/// A private key. -#[derive(Clone, Default, cbor::Encode, cbor::Decode, Zeroize)] -#[cbor(transparent)] -#[zeroize(drop)] -pub struct PrivateKey(pub [u8; 32]); - -/// A state encryption key. -#[derive(Clone, Default, cbor::Encode, cbor::Decode, Zeroize)] -#[cbor(transparent)] -#[zeroize(drop)] -pub struct StateKey(pub [u8; 32]); - -impl AsRef<[u8]> for StateKey { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -/// A 256-bit master secret. -#[derive(Clone, Default, cbor::Encode, cbor::Decode, Zeroize)] -#[cbor(transparent)] -#[zeroize(drop)] -pub struct MasterSecret(pub [u8; 32]); - -impl AsRef<[u8]> for MasterSecret { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -/// Key manager initialization request. -#[derive(Clone, Default, cbor::Encode, cbor::Decode)] -pub struct InitRequest { - /// Checksum for validating replication. - pub checksum: Vec, - /// Policy for queries/replication. - pub policy: Vec, - /// True iff the enclave may generate a new master secret. - pub may_generate: bool, -} - -/// Key manager initialization response. -#[derive(Clone, Default, cbor::Encode, cbor::Decode)] -pub struct InitResponse { - /// True iff the key manager thinks it's running in a secure mode. - pub is_secure: bool, - /// Checksum for validating replication. - pub checksum: Vec, - /// Checksum for identifying policy. - pub policy_checksum: Vec, -} - -/// Context used for the init response signature. -pub const INIT_RESPONSE_CONTEXT: &[u8] = b"oasis-core/keymanager: init response"; - -/// Signed InitResponse. -#[derive(Clone, Default, cbor::Encode, cbor::Decode)] -pub struct SignedInitResponse { - /// InitResponse. - pub init_response: InitResponse, - /// Sign(init_response). - pub signature: Signature, -} - -/// Key manager replication request. -#[derive(Clone, Default, cbor::Encode, cbor::Decode)] -pub struct ReplicateRequest { - /// Latest trust root height. - pub height: Option, -} - -impl ReplicateRequest { - pub fn new(height: Option) -> Self { - Self { height } - } -} - -/// Key manager replication response. -#[derive(Clone, Default, cbor::Encode, cbor::Decode)] -pub struct ReplicateResponse { - pub master_secret: MasterSecret, -} - -/// Long-term key request for private/public key generation and retrieval. -/// -/// Long-term keys are runtime-scoped long-lived keys derived by the key manager -/// from the master secret. They can be generated at any time. -#[derive(Clone, Default, cbor::Encode, cbor::Decode)] -pub struct LongTermKeyRequest { - /// Latest trust root height. - pub height: Option, - /// Runtime ID. - pub runtime_id: Namespace, - /// Key pair ID. - pub key_pair_id: KeyPairId, -} - -impl LongTermKeyRequest { - pub fn new(height: Option, runtime_id: Namespace, key_pair_id: KeyPairId) -> Self { - Self { - height, - runtime_id, - key_pair_id, - } - } -} - -/// Ephemeral key request for private/public key generation and retrieval. -/// -/// Ephemeral keys are runtime-scoped short-lived keys derived by -/// the key manager from the master secret. They can only be generated -/// for the past few epochs relative to the consensus layer state. -#[derive(Clone, Default, cbor::Encode, cbor::Decode)] -pub struct EphemeralKeyRequest { - /// Latest trust root height. - pub height: Option, - /// Runtime ID. - pub runtime_id: Namespace, - /// Key pair ID. - pub key_pair_id: KeyPairId, - /// Epoch time. - pub epoch: EpochTime, -} - -impl EphemeralKeyRequest { - pub fn new( - height: Option, - runtime_id: Namespace, - key_pair_id: KeyPairId, - epoch: EpochTime, - ) -> Self { - Self { - height, - runtime_id, - key_pair_id, - epoch, - } - } -} - -/// A key pair managed by the key manager. -#[derive(Clone, Default, cbor::Encode, cbor::Decode)] -pub struct KeyPair { - /// Input key pair (pk, sk) - pub input_keypair: InputKeyPair, - /// State encryption key - pub state_key: StateKey, - /// Checksum of the key manager state. - pub checksum: Vec, -} - -impl KeyPair { - /// Generate a new random key (for testing). - pub fn generate_mock() -> Self { - let mut rng = OsRng {}; - let sk = x25519_dalek::StaticSecret::new(&mut rng); - let pk = x25519_dalek::PublicKey::from(&sk); - - let mut state_key = StateKey::default(); - rng.fill(&mut state_key.0); - - KeyPair::new( - PublicKey(*pk.as_bytes()), - PrivateKey(sk.to_bytes()), - state_key, - vec![], - ) - } - - /// Create a `KeyPair`. - pub fn new(pk: PublicKey, sk: PrivateKey, k: StateKey, sum: Vec) -> Self { - Self { - input_keypair: InputKeyPair { pk, sk }, - state_key: k, - checksum: sum, - } - } - - /// Create a `KeyPair` with only the public key. - pub fn from_public_key(k: PublicKey, sum: Vec) -> Self { - Self { - input_keypair: InputKeyPair { - pk: k, - sk: PrivateKey::default(), - }, - state_key: StateKey::default(), - checksum: sum, - } - } -} - -#[derive(Clone, Default, cbor::Encode, cbor::Decode)] -pub struct InputKeyPair { - /// Public key. - pub pk: PublicKey, - /// Private key. - pub sk: PrivateKey, -} - -/// Context used for the public key signature. -pub const PUBLIC_KEY_CONTEXT: [u8; 8] = *b"EkKmPubK"; - -/// Signed public key. -#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)] -pub struct SignedPublicKey { - /// Public key. - pub key: PublicKey, - /// Checksum of the key manager state. - pub checksum: Vec, - /// Sign(sk, (key || checksum)) from the key manager. - pub signature: Signature, -} - -/// Key manager error. -#[derive(Error, Debug)] -pub enum KeyManagerError { - #[error("client session is not authenticated")] - NotAuthenticated, - #[error("client is not authorized")] - NotAuthorized, - #[error("invalid epoch")] - InvalidEpoch, - #[error("height is not fresh")] - HeightNotFresh, - #[error("key manager is not initialized")] - NotInitialized, - #[error("key manager state corrupted")] - StateCorrupted, - #[error("key manager replication required")] - ReplicationRequired, - #[error("policy rollback")] - PolicyRollback, - #[error("policy alteration, without serial increment")] - PolicyChanged, - #[error("policy has invalid runtime")] - PolicyInvalidRuntime, - #[error("policy is malformed or invalid: {0}")] - PolicyInvalid(#[from] anyhow::Error), - #[error("policy has insufficient signatures")] - PolicyInsufficientSignatures, - #[error("policy hasn't been published")] - PolicyNotPublished, - #[error(transparent)] - Other(anyhow::Error), -} - -/// Set of trusted key manager policy signing keys. -#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] -pub struct TrustedPolicySigners { - /// Set of trusted signers. - pub signers: HashSet, - /// Threshold for determining if enough valid signatures are present. - pub threshold: u64, -} - -impl Default for TrustedPolicySigners { - fn default() -> Self { - Self { - signers: HashSet::new(), - threshold: 9001, - } - } -} - -impl TrustedPolicySigners { - /// Verify that policy has valid signatures and that enough of them are from trusted signers. - pub fn verify<'a>( - &self, - signed_policy: &'a SignedPolicySGX, - ) -> Result<&'a PolicySGX, KeyManagerError> { - let policy = signed_policy - .verify() - .map_err(|err| KeyManagerError::PolicyInvalid(err.into()))?; - - self.verify_trusted_signers(signed_policy)?; - - Ok(policy) - } - - /// Verify that policy has enough signatures from trusted signers. - fn verify_trusted_signers( - &self, - signed_policy: &SignedPolicySGX, - ) -> Result<(), KeyManagerError> { - // Use set to remove duplicates. - let all: HashSet<_> = signed_policy - .signatures - .iter() - .map(|s| s.public_key) - .collect(); - let trusted: HashSet<_> = self.signers.intersection(&all).collect(); - if trusted.len() < self.threshold as usize { - return Err(KeyManagerError::PolicyInsufficientSignatures); - } - Ok(()) - } -} - -/// Name of the `get_or_create_keys` method. -pub const METHOD_GET_OR_CREATE_KEYS: &str = "get_or_create_keys"; -/// Name of the `get_public_key` method. -pub const METHOD_GET_PUBLIC_KEY: &str = "get_public_key"; -/// Name of the `get_or_create_ephemeral_keys` method. -pub const METHOD_GET_OR_CREATE_EPHEMERAL_KEYS: &str = "get_or_create_ephemeral_keys"; -/// Name of the `get_public_ephemeral_key` method. -pub const METHOD_GET_PUBLIC_EPHEMERAL_KEY: &str = "get_public_ephemeral_key"; -/// Name of the `replicate_master_secret` method. -pub const METHOD_REPLICATE_MASTER_SECRET: &str = "replicate_master_secret"; - -/// Name of the `init` local method. -pub const LOCAL_METHOD_INIT: &str = "init"; - -#[cfg(test)] -mod tests { - use std::{collections::HashSet, iter::FromIterator}; - - use crypto::signature::{PublicKey as OasisPublicKey, SignatureBundle}; - use oasis_core_runtime::{common::crypto, consensus::keymanager::SignedPolicySGX}; - - use crate::TrustedPolicySigners; - - #[test] - fn test_trusted_policy_signers() { - // Prepare data for tests. - let public_keys = vec![ - OasisPublicKey::from( - "af2c61c73142d1718fb51a7e151680ab4fea5ed0a95108e4e9d6719a6ef6186e", - ), // trusted - OasisPublicKey::from( - "2b87e78e941cccca2222dd30fca04dee45d7e652da907d607b0971422c1bde1f", - ), // trusted - OasisPublicKey::from( - "2c1378defc5a1d932c18c87008e6d33e6fcfed33312fa3224de4e3d7fcc3251c", - ), // trusted - OasisPublicKey::from( - "235ca1d91ed078a3568018bef563edfb3503afa6434dbdee8310ab6fe2df50a7", - ), - OasisPublicKey::from( - "17504048e11cbc8bc164785379f993f1a6934c3a9f10a78b178b59e85cd7c4c4", - ), - ]; - let signatures = vec![ - SignatureBundle { - public_key: public_keys[1], // trusted - ..Default::default() - }, - SignatureBundle { - public_key: public_keys[2], // trusted - ..Default::default() - }, - SignatureBundle { - public_key: public_keys[3], - ..Default::default() - }, - SignatureBundle { - public_key: public_keys[4], - ..Default::default() - }, - ]; - let trusted_signers = TrustedPolicySigners { - signers: HashSet::from_iter(vec![public_keys[0], public_keys[1], public_keys[2]]), - threshold: 2, - }; - - // Happy path, enough trust (2/3). - let policy = SignedPolicySGX { - signatures: signatures[..].to_vec(), - ..Default::default() - }; - trusted_signers - .verify_trusted_signers(&policy) - .expect("policy should be trusted"); - - // Not enough trust (1/3). - let policy = SignedPolicySGX { - signatures: signatures[1..].to_vec(), - ..Default::default() - }; - trusted_signers - .verify_trusted_signers(&policy) - .expect_err("policy should not be trusted"); - - // Multiple signatures from the same signer. - let policy = SignedPolicySGX { - signatures: vec![ - signatures[0].clone(), - signatures[0].clone(), - signatures[0].clone(), - ], - ..Default::default() - }; - trusted_signers - .verify_trusted_signers(&policy) - .expect_err("policy should not be trusted"); - } -} diff --git a/keymanager-client/Cargo.toml b/keymanager-client/Cargo.toml deleted file mode 100644 index f24e03b50e2..00000000000 --- a/keymanager-client/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "oasis-core-keymanager-client" -version = "0.0.0" -authors = ["Oasis Protocol Foundation "] -edition = "2018" - -[dependencies] -oasis-core-runtime = { path = "../runtime" } -oasis-core-keymanager-api-common = { path = "../keymanager-api-common" } -cbor = { version = "0.5.0", package = "oasis-cbor" } - -# Third party. -futures = "0.3.17" -io-context = "0.2.0" -lru = "0.7.7" -thiserror = "1.0" diff --git a/keymanager-lib/src/lib.rs b/keymanager-lib/src/lib.rs deleted file mode 100644 index e2169cb85a3..00000000000 --- a/keymanager-lib/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod context; -pub mod kdf; -pub mod keymanager; -mod methods; -pub mod policy; diff --git a/keymanager-lib/Cargo.toml b/keymanager/Cargo.toml similarity index 74% rename from keymanager-lib/Cargo.toml rename to keymanager/Cargo.toml index f4fd42350e4..c266bc2f20b 100644 --- a/keymanager-lib/Cargo.toml +++ b/keymanager/Cargo.toml @@ -1,25 +1,26 @@ [package] -name = "oasis-core-keymanager-lib" +name = "oasis-core-keymanager" version = "0.0.0" authors = ["Oasis Protocol Foundation "] edition = "2018" [dependencies] oasis-core-runtime = { path = "../runtime" } -oasis-core-keymanager-api-common = { path = "../keymanager-api-common" } -oasis-core-keymanager-client = { path = "../keymanager-client" } cbor = { version = "0.5.0", package = "oasis-cbor" } # Third party. anyhow = "1.0" +base64 = "0.13.0" +futures = "0.3.17" +io-context = "0.2.0" lazy_static = "1.3.0" lru = "0.7.7" -io-context = "0.2.0" rand = "0.7.3" +rustc-hex = "2.0.1" sgx-isa = { version = "0.3.3", features = ["sgxstd"] } sp800-185 = "0.2.0" +thiserror = "1.0" tiny-keccak = { version = "2.0.2", features = ["sha3"] } x25519-dalek = "1.1.0" tokio = { version = "~1.20", features = ["rt"] } -zeroize = "1.4" -rustc-hex = "2.0.1" +zeroize = "1.4.2" diff --git a/keymanager/src/api/errors.rs b/keymanager/src/api/errors.rs new file mode 100644 index 00000000000..b60eb31e0c7 --- /dev/null +++ b/keymanager/src/api/errors.rs @@ -0,0 +1,34 @@ +use thiserror::Error; + +/// Key manager error. +#[derive(Error, Debug)] +pub enum KeyManagerError { + #[error("client session is not authenticated")] + NotAuthenticated, + #[error("client is not authorized")] + NotAuthorized, + #[error("invalid epoch")] + InvalidEpoch, + #[error("height is not fresh")] + HeightNotFresh, + #[error("key manager is not initialized")] + NotInitialized, + #[error("key manager state corrupted")] + StateCorrupted, + #[error("key manager replication required")] + ReplicationRequired, + #[error("policy rollback")] + PolicyRollback, + #[error("policy alteration, without serial increment")] + PolicyChanged, + #[error("policy has invalid runtime")] + PolicyInvalidRuntime, + #[error("policy is malformed or invalid: {0}")] + PolicyInvalid(#[from] anyhow::Error), + #[error("policy has insufficient signatures")] + PolicyInsufficientSignatures, + #[error("policy hasn't been published")] + PolicyNotPublished, + #[error(transparent)] + Other(anyhow::Error), +} diff --git a/keymanager/src/api/methods.rs b/keymanager/src/api/methods.rs new file mode 100644 index 00000000000..0c7178b0d95 --- /dev/null +++ b/keymanager/src/api/methods.rs @@ -0,0 +1,13 @@ +/// Name of the `get_or_create_keys` method. +pub const METHOD_GET_OR_CREATE_KEYS: &str = "get_or_create_keys"; +/// Name of the `get_public_key` method. +pub const METHOD_GET_PUBLIC_KEY: &str = "get_public_key"; +/// Name of the `get_or_create_ephemeral_keys` method. +pub const METHOD_GET_OR_CREATE_EPHEMERAL_KEYS: &str = "get_or_create_ephemeral_keys"; +/// Name of the `get_public_ephemeral_key` method. +pub const METHOD_GET_PUBLIC_EPHEMERAL_KEY: &str = "get_public_ephemeral_key"; +/// Name of the `replicate_master_secret` method. +pub const METHOD_REPLICATE_MASTER_SECRET: &str = "replicate_master_secret"; + +/// Name of the `init` local method. +pub const LOCAL_METHOD_INIT: &str = "init"; diff --git a/keymanager/src/api/mod.rs b/keymanager/src/api/mod.rs new file mode 100644 index 00000000000..77b727a74a8 --- /dev/null +++ b/keymanager/src/api/mod.rs @@ -0,0 +1,7 @@ +//! Key manager API common types and functions. +mod errors; +mod methods; +mod requests; + +// Re-exports. +pub use self::{errors::*, methods::*, requests::*}; diff --git a/keymanager/src/api/requests.rs b/keymanager/src/api/requests.rs new file mode 100644 index 00000000000..b42b9a3850b --- /dev/null +++ b/keymanager/src/api/requests.rs @@ -0,0 +1,113 @@ +use oasis_core_runtime::{ + common::{crypto::signature::Signature, namespace::Namespace}, + consensus::beacon::EpochTime, +}; + +use crate::crypto::{KeyPairId, MasterSecret}; + +/// Key manager initialization request. +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] +pub struct InitRequest { + /// Checksum for validating replication. + pub checksum: Vec, + /// Policy for queries/replication. + pub policy: Vec, + /// True iff the enclave may generate a new master secret. + pub may_generate: bool, +} + +/// Key manager initialization response. +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] +pub struct InitResponse { + /// True iff the key manager thinks it's running in a secure mode. + pub is_secure: bool, + /// Checksum for validating replication. + pub checksum: Vec, + /// Checksum for identifying policy. + pub policy_checksum: Vec, +} + +/// Signed InitResponse. +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] +pub struct SignedInitResponse { + /// InitResponse. + pub init_response: InitResponse, + /// Sign(init_response). + pub signature: Signature, +} + +/// Key manager replication request. +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] +pub struct ReplicateRequest { + /// Latest trust root height. + pub height: Option, +} + +impl ReplicateRequest { + pub fn new(height: Option) -> Self { + Self { height } + } +} + +/// Key manager replication response. +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] +pub struct ReplicateResponse { + pub master_secret: MasterSecret, +} + +/// Long-term key request for private/public key generation and retrieval. +/// +/// Long-term keys are runtime-scoped long-lived keys derived by the key manager +/// from the master secret. They can be generated at any time. +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] +pub struct LongTermKeyRequest { + /// Latest trust root height. + pub height: Option, + /// Runtime ID. + pub runtime_id: Namespace, + /// Key pair ID. + pub key_pair_id: KeyPairId, +} + +impl LongTermKeyRequest { + pub fn new(height: Option, runtime_id: Namespace, key_pair_id: KeyPairId) -> Self { + Self { + height, + runtime_id, + key_pair_id, + } + } +} + +/// Ephemeral key request for private/public key generation and retrieval. +/// +/// Ephemeral keys are runtime-scoped short-lived keys derived by +/// the key manager from the master secret. They can only be generated +/// for the past few epochs relative to the consensus layer state. +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] +pub struct EphemeralKeyRequest { + /// Latest trust root height. + pub height: Option, + /// Runtime ID. + pub runtime_id: Namespace, + /// Key pair ID. + pub key_pair_id: KeyPairId, + /// Epoch time. + pub epoch: EpochTime, +} + +impl EphemeralKeyRequest { + pub fn new( + height: Option, + runtime_id: Namespace, + key_pair_id: KeyPairId, + epoch: EpochTime, + ) -> Self { + Self { + height, + runtime_id, + key_pair_id, + epoch, + } + } +} diff --git a/keymanager-client/src/lib.rs b/keymanager/src/client/interface.rs similarity index 94% rename from keymanager-client/src/lib.rs rename to keymanager/src/client/interface.rs index f49898372e0..47b0945e51c 100644 --- a/keymanager-client/src/lib.rs +++ b/keymanager/src/client/interface.rs @@ -1,16 +1,16 @@ //! Key manager client. - -pub mod client; -pub mod mock; - use std::sync::Arc; use futures::future::BoxFuture; use io_context::Context; -use oasis_core_keymanager_api_common::{self, KeyManagerError}; use oasis_core_runtime::consensus::beacon::EpochTime; +use crate::{ + api::KeyManagerError, + crypto::{KeyPair, KeyPairId, MasterSecret, SignedPublicKey}, +}; + /// Key manager client interface. pub trait KeyManagerClient: Send + Sync { /// Clear local key cache. @@ -109,6 +109,3 @@ impl KeyManagerClient for Arc { KeyManagerClient::replicate_master_secret(&**self, ctx) } } - -// Re-exports. -pub use self::{client::RemoteClient, oasis_core_keymanager_api_common::*}; diff --git a/keymanager-client/src/mock.rs b/keymanager/src/client/mock.rs similarity index 96% rename from keymanager-client/src/mock.rs rename to keymanager/src/client/mock.rs index 7b041fd7cd6..bf85fca7628 100644 --- a/keymanager-client/src/mock.rs +++ b/keymanager/src/client/mock.rs @@ -6,9 +6,14 @@ use futures::{ TryFutureExt, }; use io_context::Context; -use oasis_core_keymanager_api_common::*; + use oasis_core_runtime::{common::crypto::signature::Signature, consensus::beacon::EpochTime}; +use crate::{ + api::KeyManagerError, + crypto::{KeyPair, KeyPairId, MasterSecret, SignedPublicKey}, +}; + use super::KeyManagerClient; /// Mock key manager client which stores everything locally. diff --git a/keymanager/src/client/mod.rs b/keymanager/src/client/mod.rs new file mode 100644 index 00000000000..2cdcaa7409f --- /dev/null +++ b/keymanager/src/client/mod.rs @@ -0,0 +1,7 @@ +//! Key manager client. +mod interface; +mod mock; +mod remote; + +// Re-exports. +pub use self::{interface::KeyManagerClient, mock::MockClient, remote::RemoteClient}; diff --git a/keymanager-client/src/client.rs b/keymanager/src/client/remote.rs similarity index 96% rename from keymanager-client/src/client.rs rename to keymanager/src/client/remote.rs index 6cbe5f61cd7..91ff1dc3abb 100644 --- a/keymanager-client/src/client.rs +++ b/keymanager/src/client/remote.rs @@ -9,7 +9,6 @@ use futures::future::{self, BoxFuture}; use io_context::Context; use lru::LruCache; -use oasis_core_keymanager_api_common::*; use oasis_core_runtime::{ common::{namespace::Namespace, sgx::EnclaveIdentity}, consensus::{beacon::EpochTime, keymanager::SignedPolicySGX, verifier::Verifier}, @@ -18,6 +17,16 @@ use oasis_core_runtime::{ rak::RAK, }; +use crate::{ + api::{ + EphemeralKeyRequest, KeyManagerError, LongTermKeyRequest, ReplicateRequest, + ReplicateResponse, METHOD_GET_OR_CREATE_EPHEMERAL_KEYS, METHOD_GET_OR_CREATE_KEYS, + METHOD_GET_PUBLIC_EPHEMERAL_KEY, METHOD_GET_PUBLIC_KEY, METHOD_REPLICATE_MASTER_SECRET, + }, + crypto::{KeyPair, KeyPairId, MasterSecret, SignedPublicKey}, + policy::{set_trusted_policy_signers, verify_policy_and_trusted_signers, TrustedPolicySigners}, +}; + use super::KeyManagerClient; /// Key manager RPC endpoint. diff --git a/keymanager-lib/src/kdf.rs b/keymanager/src/crypto/kdf.rs similarity index 97% rename from keymanager-lib/src/kdf.rs rename to keymanager/src/crypto/kdf.rs index 0dedf3006be..e790a999141 100644 --- a/keymanager-lib/src/kdf.rs +++ b/keymanager/src/crypto/kdf.rs @@ -14,12 +14,6 @@ use sp800_185::{CShake, KMac}; use x25519_dalek; use zeroize::Zeroize; -use oasis_core_keymanager_api_common::{ - EphemeralKeyRequest, InitRequest, InitResponse, KeyManagerError, KeyPair, LongTermKeyRequest, - MasterSecret, PrivateKey, PublicKey, ReplicateResponse, SignedInitResponse, SignedPublicKey, - StateKey, INIT_RESPONSE_CONTEXT, PUBLIC_KEY_CONTEXT, -}; -use oasis_core_keymanager_client::{KeyManagerClient, RemoteClient}; use oasis_core_runtime::{ common::{ crypto::{ @@ -35,7 +29,22 @@ use oasis_core_runtime::{ BUILD_INFO, }; -use crate::{context::Context as KmContext, policy::Policy}; +use crate::{ + api::{ + EphemeralKeyRequest, InitRequest, InitResponse, KeyManagerError, LongTermKeyRequest, + ReplicateResponse, SignedInitResponse, + }, + client::{KeyManagerClient, RemoteClient}, + crypto::{KeyPair, MasterSecret, PrivateKey, PublicKey, SignedPublicKey, StateKey}, + policy::Policy, + runtime::context::Context as KmContext, +}; + +/// Context used for the init response signature. +const INIT_RESPONSE_CONTEXT: &[u8] = b"oasis-core/keymanager: init response"; + +/// Context used for the public key signature. +const PUBLIC_KEY_CONTEXT: [u8; 8] = *b"EkKmPubK"; lazy_static! { // Global KDF object. @@ -535,25 +544,26 @@ impl Kdf { #[cfg(test)] mod tests { - use lru::LruCache; - use rustc_hex::{FromHex, ToHex}; use std::{ collections::HashSet, convert::TryInto, sync::{Arc, RwLock}, }; - use oasis_core_keymanager_api_common::{ - EphemeralKeyRequest, KeyPairId, LongTermKeyRequest, MasterSecret, PublicKey, - PUBLIC_KEY_CONTEXT, - }; + use lru::LruCache; + use rustc_hex::{FromHex, ToHex}; + use oasis_core_runtime::common::{crypto::signature::PrivateKey, namespace::Namespace}; + use crate::{ + api::{EphemeralKeyRequest, LongTermKeyRequest}, + crypto::{KeyPairId, MasterSecret, PublicKey}, + }; + use super::{ - Inner, KeyRequest, EPHEMERAL_KDF_CUSTOM, EPHEMERAL_XOF_CUSTOM, RUNTIME_KDF_CUSTOM, - RUNTIME_XOF_CUSTOM, + Inner, Kdf, KeyRequest, EPHEMERAL_KDF_CUSTOM, EPHEMERAL_XOF_CUSTOM, PUBLIC_KEY_CONTEXT, + RUNTIME_KDF_CUSTOM, RUNTIME_XOF_CUSTOM, }; - use crate::kdf::Kdf; struct SimpleKeyRequest<'a> { seed: &'a str, diff --git a/keymanager/src/crypto/mod.rs b/keymanager/src/crypto/mod.rs new file mode 100644 index 00000000000..b785dfaada1 --- /dev/null +++ b/keymanager/src/crypto/mod.rs @@ -0,0 +1,6 @@ +//! Key manager crypto types and primitives. +pub mod kdf; +mod types; + +// Re-exports. +pub use self::types::*; diff --git a/keymanager/src/crypto/types.rs b/keymanager/src/crypto/types.rs new file mode 100644 index 00000000000..2e816302ef2 --- /dev/null +++ b/keymanager/src/crypto/types.rs @@ -0,0 +1,108 @@ +use rand::{rngs::OsRng, Rng}; +use x25519_dalek; +use zeroize::Zeroize; + +use oasis_core_runtime::{common::crypto::signature::Signature, impl_bytes}; + +impl_bytes!(KeyPairId, 32, "A 256-bit key pair identifier."); +impl_bytes!(PublicKey, 32, "A public key."); + +/// A private key. +#[derive(Clone, Default, cbor::Encode, cbor::Decode, Zeroize)] +#[cbor(transparent)] +#[zeroize(drop)] +pub struct PrivateKey(pub [u8; 32]); + +/// A state encryption key. +#[derive(Clone, Default, cbor::Encode, cbor::Decode, Zeroize)] +#[cbor(transparent)] +#[zeroize(drop)] +pub struct StateKey(pub [u8; 32]); + +impl AsRef<[u8]> for StateKey { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +/// A 256-bit master secret. +#[derive(Clone, Default, cbor::Encode, cbor::Decode, Zeroize)] +#[cbor(transparent)] +#[zeroize(drop)] +pub struct MasterSecret(pub [u8; 32]); + +impl AsRef<[u8]> for MasterSecret { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +/// A key pair managed by the key manager. +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] +pub struct KeyPair { + /// Input key pair (pk, sk) + pub input_keypair: InputKeyPair, + /// State encryption key + pub state_key: StateKey, + /// Checksum of the key manager state. + pub checksum: Vec, +} + +impl KeyPair { + /// Generate a new random key (for testing). + pub fn generate_mock() -> Self { + let mut rng = OsRng {}; + let sk = x25519_dalek::StaticSecret::new(&mut rng); + let pk = x25519_dalek::PublicKey::from(&sk); + + let mut state_key = StateKey::default(); + rng.fill(&mut state_key.0); + + KeyPair::new( + PublicKey(*pk.as_bytes()), + PrivateKey(sk.to_bytes()), + state_key, + vec![], + ) + } + + /// Create a `KeyPair`. + pub fn new(pk: PublicKey, sk: PrivateKey, k: StateKey, sum: Vec) -> Self { + Self { + input_keypair: InputKeyPair { pk, sk }, + state_key: k, + checksum: sum, + } + } + + /// Create a `KeyPair` with only the public key. + pub fn from_public_key(k: PublicKey, sum: Vec) -> Self { + Self { + input_keypair: InputKeyPair { + pk: k, + sk: PrivateKey::default(), + }, + state_key: StateKey::default(), + checksum: sum, + } + } +} + +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] +pub struct InputKeyPair { + /// Public key. + pub pk: PublicKey, + /// Private key. + pub sk: PrivateKey, +} + +/// Signed public key. +#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)] +pub struct SignedPublicKey { + /// Public key. + pub key: PublicKey, + /// Checksum of the key manager state. + pub checksum: Vec, + /// Sign(sk, (key || checksum)) from the key manager. + pub signature: Signature, +} diff --git a/keymanager/src/lib.rs b/keymanager/src/lib.rs new file mode 100644 index 00000000000..524d4a0276d --- /dev/null +++ b/keymanager/src/lib.rs @@ -0,0 +1,5 @@ +pub mod api; +pub mod client; +pub mod crypto; +pub mod policy; +pub mod runtime; diff --git a/keymanager-lib/src/policy.rs b/keymanager/src/policy/cached.rs similarity index 98% rename from keymanager-lib/src/policy.rs rename to keymanager/src/policy/cached.rs index b3eac8df200..4354ebed29a 100644 --- a/keymanager-lib/src/policy.rs +++ b/keymanager/src/policy/cached.rs @@ -11,7 +11,6 @@ use lazy_static::lazy_static; use sgx_isa::Keypolicy; use tiny_keccak::{Hasher, Sha3}; -use oasis_core_keymanager_api_common::*; use oasis_core_runtime::{ common::{ namespace::Namespace, @@ -28,11 +27,14 @@ use oasis_core_runtime::{ storage::KeyValue, }; -use crate::context::Context as KmContext; +use crate::{api::KeyManagerError, runtime::context::Context as KmContext}; + +use super::verify_policy_and_trusted_signers; lazy_static! { static ref POLICY: Policy = Policy::new(); } + const POLICY_STORAGE_KEY: &[u8] = b"keymanager_policy"; const POLICY_SEAL_CONTEXT: &[u8] = b"Ekiden Keymanager Seal policy v0"; diff --git a/keymanager-api-common/src/lib.rs b/keymanager/src/policy/global.rs similarity index 84% rename from keymanager-api-common/src/lib.rs rename to keymanager/src/policy/global.rs index db4d0997cd6..22c67d7af54 100644 --- a/keymanager-api-common/src/lib.rs +++ b/keymanager/src/policy/global.rs @@ -1,15 +1,14 @@ -//! Key manager API common types and functions. use std::sync::{Mutex, Once}; +use anyhow::Result; use lazy_static::lazy_static; -use oasis_core_runtime::consensus::keymanager::{PolicySGX, SignedPolicySGX}; +use oasis_core_runtime::{ + self, + consensus::keymanager::{PolicySGX, SignedPolicySGX}, +}; -#[macro_use] -pub mod api; - -// Re-exports. -pub use api::*; +use crate::{api::KeyManagerError, policy::TrustedPolicySigners}; lazy_static! { /// Set of trusted policy signers. diff --git a/keymanager/src/policy/mod.rs b/keymanager/src/policy/mod.rs new file mode 100644 index 00000000000..c603e7d069f --- /dev/null +++ b/keymanager/src/policy/mod.rs @@ -0,0 +1,7 @@ +//! Policy support. +mod cached; +mod global; +mod signers; + +// Re-exports. +pub use self::{cached::Policy, global::*, signers::TrustedPolicySigners}; diff --git a/keymanager/src/policy/signers.rs b/keymanager/src/policy/signers.rs new file mode 100644 index 00000000000..cee66184121 --- /dev/null +++ b/keymanager/src/policy/signers.rs @@ -0,0 +1,145 @@ +use std::collections::HashSet; + +use oasis_core_runtime::{ + common::crypto::signature::PublicKey as OasisPublicKey, + consensus::keymanager::{PolicySGX, SignedPolicySGX}, +}; + +use crate::api::KeyManagerError; + +/// Set of trusted key manager policy signing keys. +#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +pub struct TrustedPolicySigners { + /// Set of trusted signers. + pub signers: HashSet, + /// Threshold for determining if enough valid signatures are present. + pub threshold: u64, +} + +impl Default for TrustedPolicySigners { + fn default() -> Self { + Self { + signers: HashSet::new(), + threshold: 9001, + } + } +} + +impl TrustedPolicySigners { + /// Verify that policy has valid signatures and that enough of them are from trusted signers. + pub fn verify<'a>( + &self, + signed_policy: &'a SignedPolicySGX, + ) -> Result<&'a PolicySGX, KeyManagerError> { + let policy = signed_policy + .verify() + .map_err(|err| KeyManagerError::PolicyInvalid(err.into()))?; + + self.verify_trusted_signers(signed_policy)?; + + Ok(policy) + } + + /// Verify that policy has enough signatures from trusted signers. + fn verify_trusted_signers( + &self, + signed_policy: &SignedPolicySGX, + ) -> Result<(), KeyManagerError> { + // Use set to remove duplicates. + let all: HashSet<_> = signed_policy + .signatures + .iter() + .map(|s| s.public_key) + .collect(); + let trusted: HashSet<_> = self.signers.intersection(&all).collect(); + if trusted.len() < self.threshold as usize { + return Err(KeyManagerError::PolicyInsufficientSignatures); + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use std::{collections::HashSet, iter::FromIterator}; + + use crypto::signature::{PublicKey as OasisPublicKey, SignatureBundle}; + use oasis_core_runtime::{common::crypto, consensus::keymanager::SignedPolicySGX}; + + use super::TrustedPolicySigners; + + #[test] + fn test_trusted_policy_signers() { + // Prepare data for tests. + let public_keys = vec![ + OasisPublicKey::from( + "af2c61c73142d1718fb51a7e151680ab4fea5ed0a95108e4e9d6719a6ef6186e", + ), // trusted + OasisPublicKey::from( + "2b87e78e941cccca2222dd30fca04dee45d7e652da907d607b0971422c1bde1f", + ), // trusted + OasisPublicKey::from( + "2c1378defc5a1d932c18c87008e6d33e6fcfed33312fa3224de4e3d7fcc3251c", + ), // trusted + OasisPublicKey::from( + "235ca1d91ed078a3568018bef563edfb3503afa6434dbdee8310ab6fe2df50a7", + ), + OasisPublicKey::from( + "17504048e11cbc8bc164785379f993f1a6934c3a9f10a78b178b59e85cd7c4c4", + ), + ]; + let signatures = vec![ + SignatureBundle { + public_key: public_keys[1], // trusted + ..Default::default() + }, + SignatureBundle { + public_key: public_keys[2], // trusted + ..Default::default() + }, + SignatureBundle { + public_key: public_keys[3], + ..Default::default() + }, + SignatureBundle { + public_key: public_keys[4], + ..Default::default() + }, + ]; + let trusted_signers = TrustedPolicySigners { + signers: HashSet::from_iter(vec![public_keys[0], public_keys[1], public_keys[2]]), + threshold: 2, + }; + + // Happy path, enough trust (2/3). + let policy = SignedPolicySGX { + signatures: signatures[..].to_vec(), + ..Default::default() + }; + trusted_signers + .verify_trusted_signers(&policy) + .expect("policy should be trusted"); + + // Not enough trust (1/3). + let policy = SignedPolicySGX { + signatures: signatures[1..].to_vec(), + ..Default::default() + }; + trusted_signers + .verify_trusted_signers(&policy) + .expect_err("policy should not be trusted"); + + // Multiple signatures from the same signer. + let policy = SignedPolicySGX { + signatures: vec![ + signatures[0].clone(), + signatures[0].clone(), + signatures[0].clone(), + ], + ..Default::default() + }; + trusted_signers + .verify_trusted_signers(&policy) + .expect_err("policy should not be trusted"); + } +} diff --git a/keymanager-lib/src/context.rs b/keymanager/src/runtime/context.rs similarity index 100% rename from keymanager-lib/src/context.rs rename to keymanager/src/runtime/context.rs diff --git a/keymanager-lib/src/keymanager.rs b/keymanager/src/runtime/init.rs similarity index 89% rename from keymanager-lib/src/keymanager.rs rename to keymanager/src/runtime/init.rs index 22f01631b34..fa7291bf13f 100644 --- a/keymanager-lib/src/keymanager.rs +++ b/keymanager/src/runtime/init.rs @@ -1,6 +1,5 @@ use anyhow::Result; -use oasis_core_keymanager_api_common::*; use oasis_core_runtime::{ dispatcher::{Initializer, PostInitState, PreInitState}, enclave_rpc::{ @@ -9,7 +8,17 @@ use oasis_core_runtime::{ }, }; -use crate::{context, kdf::Kdf, methods, policy::Policy}; +use crate::{ + api::{ + InitRequest, SignedInitResponse, LOCAL_METHOD_INIT, METHOD_GET_OR_CREATE_EPHEMERAL_KEYS, + METHOD_GET_OR_CREATE_KEYS, METHOD_GET_PUBLIC_EPHEMERAL_KEY, METHOD_GET_PUBLIC_KEY, + METHOD_REPLICATE_MASTER_SECRET, + }, + crypto::kdf::Kdf, + policy::{set_trusted_policy_signers, Policy, TrustedPolicySigners}, +}; + +use super::{context, methods}; /// Initialize the Kdf. fn init_kdf(req: &InitRequest, ctx: &mut RpcContext) -> Result { diff --git a/keymanager-lib/src/methods.rs b/keymanager/src/runtime/methods.rs similarity index 95% rename from keymanager-lib/src/methods.rs rename to keymanager/src/runtime/methods.rs index 2982f1640ef..c5db5ef7202 100644 --- a/keymanager-lib/src/methods.rs +++ b/keymanager/src/runtime/methods.rs @@ -1,14 +1,22 @@ //! Methods exported to remote clients via EnclaveRPC. -use crate::{kdf::Kdf, policy::Policy}; use anyhow::Result; use io_context::Context; -use oasis_core_keymanager_api_common::*; + use oasis_core_runtime::{ common::{namespace::Namespace, sgx::EnclaveIdentity}, consensus::{beacon::EpochTime, state::beacon::ImmutableState as BeaconState}, enclave_rpc::Context as RpcContext, }; +use crate::{ + api::{ + EphemeralKeyRequest, KeyManagerError, LongTermKeyRequest, ReplicateRequest, + ReplicateResponse, + }, + crypto::{kdf::Kdf, KeyPair, SignedPublicKey}, + policy::Policy, +}; + /// Maximum age of an ephemeral key in the number of epochs. const MAX_EPHEMERAL_KEY_AGE: EpochTime = 10; /// Maximum age of a fresh height in the number of blocks. diff --git a/keymanager/src/runtime/mod.rs b/keymanager/src/runtime/mod.rs new file mode 100644 index 00000000000..34284f5cc3e --- /dev/null +++ b/keymanager/src/runtime/mod.rs @@ -0,0 +1,4 @@ +//! Key manager server. +pub mod context; +pub mod init; +mod methods; diff --git a/runtime/src/consensus/keymanager.rs b/runtime/src/consensus/keymanager.rs index dcc86eb2847..5a751bda4e9 100644 --- a/runtime/src/consensus/keymanager.rs +++ b/runtime/src/consensus/keymanager.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, default::Default}; +use std::collections::HashMap; use thiserror::Error; diff --git a/runtime/src/consensus/state/keymanager.rs b/runtime/src/consensus/state/keymanager.rs index 4dfd6e0b3fc..951bf02a287 100644 --- a/runtime/src/consensus/state/keymanager.rs +++ b/runtime/src/consensus/state/keymanager.rs @@ -1,6 +1,4 @@ //! Key manager state in the consensus layer. -use std::default::Default; - use anyhow::anyhow; use io_context::Context; diff --git a/tests/runtimes/simple-keymanager/Cargo.toml b/tests/runtimes/simple-keymanager/Cargo.toml index b7fed5f3340..8447915c373 100644 --- a/tests/runtimes/simple-keymanager/Cargo.toml +++ b/tests/runtimes/simple-keymanager/Cargo.toml @@ -21,8 +21,7 @@ threads = 6 [dependencies] oasis-core-runtime = { path = "../../../runtime" } -oasis-core-keymanager-lib = { path = "../../../keymanager-lib" } -oasis-core-keymanager-api-common = { path = "../../../keymanager-api-common" } +oasis-core-keymanager = { path = "../../../keymanager" } [build-dependencies] oasis-core-tools = { path = "../../../tools" } diff --git a/tests/runtimes/simple-keymanager/src/api.rs b/tests/runtimes/simple-keymanager/src/api.rs index 2f6397e6ce0..d1a9bcde4cd 100644 --- a/tests/runtimes/simple-keymanager/src/api.rs +++ b/tests/runtimes/simple-keymanager/src/api.rs @@ -1,6 +1,6 @@ use std::collections::HashSet; -use oasis_core_keymanager_api_common::*; +use oasis_core_keymanager::policy::TrustedPolicySigners; use oasis_core_runtime::common::crypto::signature::PrivateKey as OasisPrivateKey; pub fn trusted_policy_signers() -> TrustedPolicySigners { diff --git a/tests/runtimes/simple-keymanager/src/main.rs b/tests/runtimes/simple-keymanager/src/main.rs index 889abd8ae72..f7acbde66af 100644 --- a/tests/runtimes/simple-keymanager/src/main.rs +++ b/tests/runtimes/simple-keymanager/src/main.rs @@ -1,4 +1,4 @@ -use oasis_core_keymanager_lib::keymanager::*; +use oasis_core_keymanager::runtime::init::new_keymanager; use oasis_core_runtime::{common::version::Version, config::Config}; mod api; diff --git a/tests/runtimes/simple-keyvalue/Cargo.toml b/tests/runtimes/simple-keyvalue/Cargo.toml index 132812d6ff2..95ca935fc61 100644 --- a/tests/runtimes/simple-keyvalue/Cargo.toml +++ b/tests/runtimes/simple-keyvalue/Cargo.toml @@ -22,8 +22,7 @@ threads = 6 [dependencies] cbor = { version = "0.5.0", package = "oasis-cbor" } oasis-core-runtime = { path = "../../../runtime" } -oasis-core-keymanager-client = { path = "../../../keymanager-client" } -oasis-core-keymanager-api-common = { path = "../../../keymanager-api-common" } +oasis-core-keymanager = { path = "../../../keymanager" } simple-keymanager = { path = "../simple-keymanager" } # Third party. diff --git a/tests/runtimes/simple-keyvalue/src/main.rs b/tests/runtimes/simple-keyvalue/src/main.rs index f240d992eaf..bb638285a42 100644 --- a/tests/runtimes/simple-keyvalue/src/main.rs +++ b/tests/runtimes/simple-keyvalue/src/main.rs @@ -9,7 +9,7 @@ use std::{ sync::{atomic::AtomicBool, Arc}, }; -use oasis_core_keymanager_client::KeyManagerClient; +use oasis_core_keymanager::client::KeyManagerClient; use oasis_core_runtime::{ common::{crypto::hash::Hash, version::Version}, config::Config, @@ -366,7 +366,7 @@ pub fn main_with_version(version: Version) { let hi = state.protocol.get_host_info(); // Create the key manager client. - let km_client = Arc::new(oasis_core_keymanager_client::RemoteClient::new_runtime( + let km_client = Arc::new(oasis_core_keymanager::client::RemoteClient::new_runtime( hi.runtime_id, state.protocol.clone(), state.consensus_verifier.clone(), diff --git a/tests/runtimes/simple-keyvalue/src/methods.rs b/tests/runtimes/simple-keyvalue/src/methods.rs index 6815a3a0df4..a69c011ef71 100644 --- a/tests/runtimes/simple-keyvalue/src/methods.rs +++ b/tests/runtimes/simple-keyvalue/src/methods.rs @@ -6,7 +6,7 @@ use io_context::Context as IoContext; use x25519_dalek; use super::{crypto::EncryptionContext, types::*, Context, TxContext}; -use oasis_core_keymanager_client::KeyPairId; +use oasis_core_keymanager::crypto::KeyPairId; use oasis_core_runtime::{ common::{ crypto::{