Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keymanager: Rename APIs referencing "contracts" #2979

Merged
merged 1 commit into from
Jun 4, 2020
Merged
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: 5 additions & 0 deletions .changelog/2844.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
keymanager: Rename APIs referencing "contracts"

Each runtime does not neccecarily have a notion for contracts, so the
key manager now operates in terms of `KeyPairId`s that identify a given
`KeyPair`.
28 changes: 14 additions & 14 deletions keymanager-api-common/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use oasis_core_runtime::{
impl_bytes, runtime_api,
};

impl_bytes!(ContractId, 32, "A 256-bit contract identifier.");
impl_bytes!(KeyPairId, 32, "A 256-bit key pair identifier.");
impl_bytes!(PrivateKey, 32, "A private key.");
impl_bytes!(PublicKey, 32, "A public key.");
impl_bytes!(StateKey, 32, "A state key.");
Expand Down Expand Up @@ -74,33 +74,33 @@ pub struct ReplicateResponse {
pub master_secret: MasterSecret,
}

/// Request runtime/contract id tuple.
/// Request runtime/key pair id tuple.
#[derive(Clone, Serialize, Deserialize)]
pub struct RequestIds {
/// Runtime ID.
pub runtime_id: RuntimeId,
/// Contract ID.
pub contract_id: ContractId,
/// Key pair ID.
pub key_pair_id: KeyPairId,
}

impl RequestIds {
pub fn new(runtime_id: RuntimeId, contract_id: ContractId) -> Self {
pub fn new(runtime_id: RuntimeId, key_pair_id: KeyPairId) -> Self {
Self {
runtime_id,
contract_id,
key_pair_id,
}
}

pub fn to_cache_key(&self) -> Vec<u8> {
let mut k = self.runtime_id.as_ref().to_vec();
k.extend_from_slice(self.contract_id.as_ref());
k.extend_from_slice(self.key_pair_id.as_ref());
k
}
}

/// Keys for a contract.
/// A key pair managed by the key manager.
#[derive(Clone, Serialize, Deserialize)]
pub struct ContractKey {
pub struct KeyPair {
/// Input key pair (pk, sk)
pub input_keypair: InputKeyPair,
/// State encryption key
Expand All @@ -110,7 +110,7 @@ pub struct ContractKey {
pub checksum: Vec<u8>,
}

impl ContractKey {
impl KeyPair {
/// Generate a new random key (for testing).
pub fn generate_mock() -> Self {
let mut rng = OsRng {};
Expand All @@ -120,15 +120,15 @@ impl ContractKey {
let mut state_key = StateKey::default();
rng.fill(&mut state_key.0);

ContractKey::new(
KeyPair::new(
PublicKey(*pk.as_bytes()),
PrivateKey(sk.to_bytes()),
state_key,
vec![],
)
}

/// Create a set of `ContractKey`.
/// Create a `KeyPair`.
pub fn new(pk: PublicKey, sk: PrivateKey, k: StateKey, sum: Vec<u8>) -> Self {
Self {
input_keypair: InputKeyPair::new(pk, sk),
Expand All @@ -137,7 +137,7 @@ impl ContractKey {
}
}

/// Create a set of `ContractKey` with only the public key.
/// Create a `KeyPair` with only the public key.
pub fn from_public_key(k: PublicKey, sum: Vec<u8>) -> Self {
Self {
input_keypair: InputKeyPair::new(k, PrivateKey::default()),
Expand Down Expand Up @@ -250,7 +250,7 @@ impl Default for TrustedPolicySigners {
}

runtime_api! {
pub fn get_or_create_keys(RequestIds) -> ContractKey;
pub fn get_or_create_keys(RequestIds) -> KeyPair;

pub fn get_public_key(RequestIds) -> Option<SignedPublicKey>;

Expand Down
20 changes: 10 additions & 10 deletions keymanager-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ struct Inner {
/// RPC client.
rpc_client: Client,
/// Local cache for the get_or_create_keys KeyManager endpoint.
get_or_create_secret_keys_cache: RwLock<LruCache<ContractId, ContractKey>>,
get_or_create_secret_keys_cache: RwLock<LruCache<KeyPairId, KeyPair>>,
/// Local cache for the get_public_key KeyManager endpoint.
get_public_key_cache: RwLock<LruCache<ContractId, SignedPublicKey>>,
get_public_key_cache: RwLock<LruCache<KeyPairId, SignedPublicKey>>,
}

/// A key manager client which talks to a remote key manager enclave.
Expand Down Expand Up @@ -158,9 +158,9 @@ impl KeyManagerClient for RemoteClient {
drop(cache);
}

fn get_or_create_keys(&self, ctx: Context, contract_id: ContractId) -> BoxFuture<ContractKey> {
fn get_or_create_keys(&self, ctx: Context, key_pair_id: KeyPairId) -> BoxFuture<KeyPair> {
let mut cache = self.inner.get_or_create_secret_keys_cache.write().unwrap();
if let Some(keys) = cache.get(&contract_id) {
if let Some(keys) = cache.get(&key_pair_id) {
return Box::new(future::ok(keys.clone()));
}

Expand All @@ -169,10 +169,10 @@ impl KeyManagerClient for RemoteClient {
Box::new(
self.inner
.rpc_client
.get_or_create_keys(ctx, RequestIds::new(inner.runtime_id, contract_id))
.get_or_create_keys(ctx, RequestIds::new(inner.runtime_id, key_pair_id))
.and_then(move |keys| {
let mut cache = inner.get_or_create_secret_keys_cache.write().unwrap();
cache.put(contract_id, keys.clone());
cache.put(key_pair_id, keys.clone());

Ok(keys)
}),
Expand All @@ -182,10 +182,10 @@ impl KeyManagerClient for RemoteClient {
fn get_public_key(
&self,
ctx: Context,
contract_id: ContractId,
key_pair_id: KeyPairId,
) -> BoxFuture<Option<SignedPublicKey>> {
let mut cache = self.inner.get_public_key_cache.write().unwrap();
if let Some(key) = cache.get(&contract_id) {
if let Some(key) = cache.get(&key_pair_id) {
return Box::new(future::ok(Some(key.clone())));
}

Expand All @@ -194,11 +194,11 @@ impl KeyManagerClient for RemoteClient {
Box::new(
self.inner
.rpc_client
.get_public_key(ctx, RequestIds::new(inner.runtime_id, contract_id))
.get_public_key(ctx, RequestIds::new(inner.runtime_id, key_pair_id))
.and_then(move |key| match key {
Some(key) => {
let mut cache = inner.get_public_key_cache.write().unwrap();
cache.put(contract_id, key.clone());
cache.put(key_pair_id, key.clone());

Ok(Some(key))
}
Expand Down
16 changes: 8 additions & 8 deletions keymanager-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ pub trait KeyManagerClient: Send + Sync {
/// This will make the client re-fetch the keys from the key manager.
fn clear_cache(&self);

/// Get or create named key.
/// Get or create named key pair.
///
/// If the key does not yet exist, the key manager will generate one. If
/// the key has already been cached locally, it will be retrieved from
/// cache.
fn get_or_create_keys(&self, ctx: Context, contract_id: ContractId) -> BoxFuture<ContractKey>;
fn get_or_create_keys(&self, ctx: Context, key_pair_id: KeyPairId) -> BoxFuture<KeyPair>;

/// Get public key for a contract.
/// Get public key for a key pair id.
fn get_public_key(
&self,
ctx: Context,
contract_id: ContractId,
key_pair_id: KeyPairId,
) -> BoxFuture<Option<SignedPublicKey>>;

/// Get a copy of the master secret for replication.
Expand All @@ -39,16 +39,16 @@ impl<T: ?Sized + KeyManagerClient> KeyManagerClient for Arc<T> {
KeyManagerClient::clear_cache(&**self)
}

fn get_or_create_keys(&self, ctx: Context, contract_id: ContractId) -> BoxFuture<ContractKey> {
KeyManagerClient::get_or_create_keys(&**self, ctx, contract_id)
fn get_or_create_keys(&self, ctx: Context, key_pair_id: KeyPairId) -> BoxFuture<KeyPair> {
KeyManagerClient::get_or_create_keys(&**self, ctx, key_pair_id)
}

fn get_public_key(
&self,
ctx: Context,
contract_id: ContractId,
key_pair_id: KeyPairId,
) -> BoxFuture<Option<SignedPublicKey>> {
KeyManagerClient::get_public_key(&**self, ctx, contract_id)
KeyManagerClient::get_public_key(&**self, ctx, key_pair_id)
}

fn replicate_master_secret(&self, ctx: Context) -> BoxFuture<Option<MasterSecret>> {
Expand Down
14 changes: 7 additions & 7 deletions keymanager-client/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use super::KeyManagerClient;

/// Mock key manager client which stores everything locally.
pub struct MockClient {
keys: Mutex<HashMap<ContractId, ContractKey>>,
keys: Mutex<HashMap<KeyPairId, KeyPair>>,
}

impl MockClient {
Expand All @@ -26,13 +26,13 @@ impl MockClient {
impl KeyManagerClient for MockClient {
fn clear_cache(&self) {}

fn get_or_create_keys(&self, _ctx: Context, contract_id: ContractId) -> BoxFuture<ContractKey> {
fn get_or_create_keys(&self, _ctx: Context, key_pair_id: KeyPairId) -> BoxFuture<KeyPair> {
let mut keys = self.keys.lock().unwrap();
let key = match keys.get(&contract_id) {
let key = match keys.get(&key_pair_id) {
Some(key) => key.clone(),
None => {
let key = ContractKey::generate_mock();
keys.insert(contract_id, key.clone());
let key = KeyPair::generate_mock();
keys.insert(key_pair_id, key.clone());
key
}
};
Expand All @@ -43,9 +43,9 @@ impl KeyManagerClient for MockClient {
fn get_public_key(
&self,
ctx: Context,
contract_id: ContractId,
key_pair_id: KeyPairId,
) -> BoxFuture<Option<SignedPublicKey>> {
Box::new(self.get_or_create_keys(ctx, contract_id).map(|ck| {
Box::new(self.get_or_create_keys(ctx, key_pair_id).map(|ck| {
Some(SignedPublicKey {
key: ck.input_keypair.get_pk(),
checksum: vec![],
Expand Down
12 changes: 6 additions & 6 deletions keymanager-lib/src/kdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use x25519_dalek;
use zeroize::Zeroize;

use oasis_core_keymanager_api_common::{
ContractKey, InitRequest, InitResponse, KeyManagerError, MasterSecret, PrivateKey, PublicKey,
InitRequest, InitResponse, KeyManagerError, KeyPair, MasterSecret, PrivateKey, PublicKey,
ReplicateResponse, RequestIds, SignedInitResponse, SignedPublicKey, StateKey,
INIT_RESPONSE_CONTEXT, PUBLIC_KEY_CONTEXT,
};
Expand Down Expand Up @@ -88,7 +88,7 @@ struct Inner {
checksum: Option<Vec<u8>>,
runtime_id: Option<RuntimeId>,
signer: Option<Arc<dyn signature::Signer>>,
cache: LruCache<Vec<u8>, ContractKey>,
cache: LruCache<Vec<u8>, KeyPair>,
}

impl Inner {
Expand All @@ -100,7 +100,7 @@ impl Inner {
self.cache.clear();
}

fn derive_contract_key(&self, req: &RequestIds) -> Fallible<ContractKey> {
fn derive_contract_key(&self, req: &RequestIds) -> Fallible<KeyPair> {
let checksum = self.get_checksum()?;
let mut contract_secret = self.derive_contract_secret(req)?;

Expand All @@ -121,7 +121,7 @@ impl Inner {
k.zeroize();
let pk = x25519_dalek::PublicKey::from(&sk);

Ok(ContractKey::new(
Ok(KeyPair::new(
PublicKey(*pk.as_bytes()),
PrivateKey(sk.to_bytes()),
state_key,
Expand All @@ -140,7 +140,7 @@ impl Inner {
// KMAC256(master_secret, runtimeID || contractID, 32, "ekiden-derive-runtime-secret")
let mut f = KMac::new_kmac256(master_secret.as_ref(), &RUNTIME_KDF_CUSTOM);
f.update(req.runtime_id.as_ref());
f.update(req.contract_id.as_ref());
f.update(req.key_pair_id.as_ref());
f.finalize(&mut k);

Ok(k.to_vec())
Expand Down Expand Up @@ -326,7 +326,7 @@ impl Kdf {
}

// Get or create keys.
pub fn get_or_create_keys(&self, req: &RequestIds) -> Fallible<ContractKey> {
pub fn get_or_create_keys(&self, req: &RequestIds) -> Fallible<KeyPair> {
let cache_key = req.to_cache_key();

// Check to see if the cached value exists.
Expand Down
2 changes: 1 addition & 1 deletion keymanager-lib/src/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use oasis_core_runtime::rpc::Context as RpcContext;
use crate::{kdf::Kdf, policy::Policy};

/// See `Kdf::get_or_create_keys`.
pub fn get_or_create_keys(req: &RequestIds, ctx: &mut RpcContext) -> Fallible<ContractKey> {
pub fn get_or_create_keys(req: &RequestIds, ctx: &mut RpcContext) -> Fallible<KeyPair> {
// Authenticate the source enclave based on the MRSIGNER/MRENCLAVE/request
// so that the keys are never released to an incorrect enclave.
if !Policy::unsafe_skip() {
Expand Down
10 changes: 5 additions & 5 deletions tests/clients/simple-keyvalue-enc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use io_context::Context;
use tokio::runtime::Runtime;

use oasis_core_client::{create_txn_api_client, Node, TxnClient};
use oasis_core_keymanager_client::{self, ContractId, KeyManagerClient};
use oasis_core_keymanager_client::{self, KeyManagerClient, KeyPairId};
use oasis_core_runtime::common::{crypto::hash::Hash, runtime::RuntimeId};
use simple_keyvalue_api::{with_api, KeyValue};

Expand Down Expand Up @@ -94,16 +94,16 @@ fn main() {
1024,
));

// Request public key for some "contract id".
let contract_id = ContractId::from(Hash::empty_hash().as_ref());
// Request public key for some "key pair id".
let key_pair_id = KeyPairId::from(Hash::empty_hash().as_ref());
let r = rt
.block_on(km_client.get_public_key(Context::background(), contract_id))
.block_on(km_client.get_public_key(Context::background(), key_pair_id))
.unwrap();
assert!(r.is_some(), "get_public_key should return a public key");
let pkey = r;

let r = rt
.block_on(km_client.get_public_key(Context::background(), contract_id))
.block_on(km_client.get_public_key(Context::background(), key_pair_id))
.unwrap();
assert_eq!(r, pkey, "get_public_key should return the same public key");

Expand Down
8 changes: 4 additions & 4 deletions tests/runtimes/simple-keyvalue/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::Arc;
use failure::{format_err, Fallible};
use io_context::Context as IoContext;

use oasis_core_keymanager_client::{ContractId, KeyManagerClient};
use oasis_core_keymanager_client::{KeyManagerClient, KeyPairId};
use oasis_core_runtime::{
common::{
crypto::{
Expand Down Expand Up @@ -88,12 +88,12 @@ fn remove(args: &String, ctx: &mut TxnContext) -> Fallible<Option<String>> {
fn get_encryption_context(ctx: &mut TxnContext, key: &[u8]) -> Fallible<EncryptionContext> {
let rctx = runtime_context!(ctx, Context);

// Derive contract ID based on key.
let contract_id = ContractId::from(Hash::digest_bytes(key).as_ref());
// Derive key pair ID based on key.
let key_pair_id = KeyPairId::from(Hash::digest_bytes(key).as_ref());

// Fetch encryption keys.
let io_ctx = IoContext::create_child(&ctx.io_ctx);
let result = rctx.km_client.get_or_create_keys(io_ctx, contract_id);
let result = rctx.km_client.get_or_create_keys(io_ctx, key_pair_id);
let key = Executor::with_current(|executor| executor.block_on(result))?;

Ok(EncryptionContext::new(key.state_key.as_ref()))
Expand Down