Skip to content

Commit

Permalink
key-manager: new unsecret signing and keystore encryption key
Browse files Browse the repository at this point in the history
  • Loading branch information
pro-wh committed Feb 26, 2019
1 parent 215b65c commit a95bc5b
Show file tree
Hide file tree
Showing 17 changed files with 210 additions and 27 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ members = [
"key-manager/api",
"key-manager/common",
"key-manager/client",
"key-manager/dummy/edl",
"key-manager/dummy/enclave",
"key-manager/dummy/keygen",
"key-manager/dummy/untrusted",
"key-manager/node",
]
Expand Down
9 changes: 9 additions & 0 deletions key-manager/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,12 @@ impl ContractKey {
}
}
}

/// A set of keys for internal use by the dummy key manager.
#[derive(Serialize, Deserialize)]
pub struct DummyInternalKeys {
#[serde(with = "BigArray")]
pub keystore_encryption_key: StateKeyType,
/// Ed25519 keypair in PKCS8 format.
pub signing_key: Vec<u8>,
}
13 changes: 13 additions & 0 deletions key-manager/dummy/edl/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "ekiden-keymanager-edl"
version = "0.2.0-alpha"
authors = ["Oasis Labs Inc. <[email protected]>"]
edition = "2018"
description = "EDL additions for the dummy key manager"
keywords = ["ekiden"]
repository = "https://github.com/oasislabs/ekiden"

[dependencies]
sgx_edl = { git = "https://github.com/oasislabs/rust-sgx-sdk", tag = "v1.0.5-ekiden1" }

ekiden-edl = { path = "../../../core/edl" }
12 changes: 12 additions & 0 deletions key-manager/dummy/edl/src/keymanager.edl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
enclave {
trusted {
/**
* Use the given internal keys, provided as a CBOR-serialized ekiden_keymanager_common::DummyInternalKeys
* structure.
*/
public void set_internal_keys(
[in, size=internal_keys_length] uint8_t *internal_keys,
size_t internal_keys_length
);
};
};
10 changes: 10 additions & 0 deletions key-manager/dummy/edl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
extern crate sgx_edl;
use sgx_edl::define_edl;

extern crate ekiden_edl;

define_edl! {
use ekiden_edl;

"keymanager.edl"
}
2 changes: 1 addition & 1 deletion key-manager/dummy/enclave/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ byteorder = "1"

[build-dependencies]
ekiden-tools = { path = "../../../tools", version = "0.2.0-alpha" }
ekiden-edl = { path = "../../../core/edl", version = "0.2.0-alpha" }
ekiden-keymanager-edl = { path = "../edl", version = "0.2.0-alpha" }
4 changes: 2 additions & 2 deletions key-manager/dummy/enclave/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
extern crate ekiden_edl;
extern crate ekiden_keymanager_edl;
extern crate ekiden_tools;

fn main() {
ekiden_tools::build_trusted(ekiden_edl::get_edls().unwrap());
ekiden_tools::build_trusted(ekiden_keymanager_edl::get_edls().unwrap());
}
28 changes: 20 additions & 8 deletions key-manager/dummy/enclave/src/key_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,19 @@ use ekiden_keymanager_common::{
};
use ekiden_trusted::db::{Database, DatabaseHandle};

/// A dummy key for use in tests where confidentiality is not needed.
const UNSECRET_ENCRYPTION_KEY: StateKeyType = [
119, 206, 190, 82, 117, 21, 62, 84, 119, 212, 117, 60, 32, 158, 183, 32, 68, 55, 131, 112, 38,
169, 217, 219, 58, 109, 194, 211, 89, 39, 198, 204, 254, 104, 202, 114, 203, 213, 89, 44, 192,
168, 42, 136, 220, 230, 66, 74, 197, 220, 22, 146, 84, 121, 175, 216, 144, 182, 40, 179, 6, 73,
177, 9,
];

/// Key store, which actually stores the key manager keys.
pub struct KeyStore;
pub struct KeyStore {
/// Dummy encryption key
encryption_key: StateKeyType,
}

lazy_static! {
// Global key store object.
Expand All @@ -26,7 +37,9 @@ lazy_static! {

impl KeyStore {
fn new() -> Self {
let mut key_store = KeyStore;
let mut key_store = KeyStore {
encryption_key: UNSECRET_ENCRYPTION_KEY,
};
// for testing purpose, insert a special key at address 0
key_store
.get_or_create_keys(ContractId::from_str(&"0".repeat(64)).unwrap())
Expand Down Expand Up @@ -83,11 +96,10 @@ impl KeyStore {

/// Dummy encryption key
pub fn encryption_key(&self) -> StateKeyType {
[
255, 135, 103, 97, 49, 33, 200, 139, 130, 186, 54, 177, 83, 2, 162, 146, 160, 234, 231,
218, 124, 160, 72, 113, 26, 177, 100, 40, 135, 129, 195, 50, 161, 220, 212, 120, 240,
163, 240, 23, 9, 74, 150, 87, 253, 60, 105, 170, 133, 134, 109, 248, 100, 43, 4, 19,
39, 25, 13, 138, 28, 49, 71, 49,
]
self.encryption_key
}

pub fn set_encryption_key(&mut self, encryption_key: StateKeyType) {
self.encryption_key = encryption_key;
}
}
45 changes: 35 additions & 10 deletions key-manager/dummy/enclave/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ extern crate lazy_static;
extern crate protobuf;
extern crate serde_cbor;
extern crate sodalite;
#[cfg(not(target_env = "sgx"))]
use std::sync::Mutex;
#[cfg(target_env = "sgx")]
use std::sync::SgxMutex as Mutex;

extern crate ekiden_core;
extern crate ekiden_keymanager_api;
Expand Down Expand Up @@ -104,6 +108,20 @@ pub fn long_term_public_key(
Ok(Some(response))
}

/// ECALL, see edl
#[cfg(target_env = "sgx")]
#[no_mangle]
pub extern "C" fn set_internal_keys(internal_keys: *const u8, internal_keys_length: usize) {
let internal_keys_buf =
unsafe { std::slice::from_raw_parts(internal_keys, internal_keys_length) };
let internal_keys: ekiden_keymanager_common::DummyInternalKeys =
serde_cbor::from_slice(internal_keys_buf).unwrap();

key_store::KeyStore::get().set_encryption_key(internal_keys.keystore_encryption_key);

*(SIGNER_KEY_PKCS8.lock().unwrap()) = internal_keys.signing_key;
}

fn sign_public_key(public_key: PublicKeyType, timestamp: Option<u64>) -> Result<B512> {
let signer = dummy_signer()?;
let digest = public_key_digest(public_key, timestamp);
Expand All @@ -120,21 +138,28 @@ fn public_key_digest(public_key: PublicKeyType, timestamp: Option<u64>) -> H256
hash::from_bytes(hash_data.as_slice())
}

/// A dummy key for use in tests where integrity is not needed.
/// Public Key: 0x9d41a874b80e39a40c9644e964f0e4f967100c91654bfd7666435fe906af060f
const UNSECRET_SIGNING_KEY_PKCS8: [u8; 85] = [
48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 109, 124, 181, 54, 35, 91, 34, 238,
29, 127, 17, 115, 64, 41, 135, 165, 19, 211, 246, 106, 37, 136, 149, 157, 187, 145, 157, 192,
170, 25, 201, 141, 161, 35, 3, 33, 0, 157, 65, 168, 116, 184, 14, 57, 164, 12, 150, 68, 233,
100, 240, 228, 249, 103, 16, 12, 145, 101, 75, 253, 118, 102, 67, 95, 233, 6, 175, 6, 15,
];

lazy_static! {
// Global key store object.
static ref SIGNER_KEY_PKCS8: Mutex<Vec<u8>> = Mutex::new(UNSECRET_SIGNING_KEY_PKCS8.to_vec());
}

/// Returns a dummy signer used by the KeyManager to sign public keys.
/// Public Key: 0x51d5e24342ae2c4a951e24a2ba45a68106bcb7986198817331889264fd10f1bf
///
/// This should be replaced as part of the following issue:
/// https://github.com/oasislabs/ekiden/issues/1291
fn dummy_signer() -> Result<InMemorySigner> {
let pkc8s = [
48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 255, 135, 103, 97, 49, 33, 200,
139, 130, 186, 54, 177, 83, 2, 162, 146, 160, 234, 231, 218, 124, 160, 72, 113, 26, 177,
100, 40, 135, 129, 195, 50, 161, 35, 3, 33, 0, 81, 213, 226, 67, 66, 174, 44, 74, 149, 30,
36, 162, 186, 69, 166, 129, 6, 188, 183, 152, 97, 152, 129, 115, 49, 136, 146, 100, 253,
16, 241, 191,
];
let pkc8s_input = untrusted::Input::from(&pkc8s);
let keypair = signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(pkc8s_input)
let guard = SIGNER_KEY_PKCS8.lock().unwrap();
let pkcs8_input = untrusted::Input::from(guard.as_slice());
let keypair = signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(pkcs8_input)
.expect("Should always derive a keypair from the given pkc8s");

Ok(InMemorySigner::new(keypair))
Expand Down
17 changes: 17 additions & 0 deletions key-manager/dummy/keygen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "ekiden-keymanager-keygen"
version = "0.2.0-alpha"
authors = ["Oasis Labs Inc. <[email protected]>"]
edition = "2018"
description = "A tool for generating a set of internal keys used by the Ekiden dummy key manager"
keywords = ["ekiden"]
repository = "https://github.com/oasislabs/ekiden"

[dependencies]
protobuf = "~2.0"
ring = { git = "https://github.com/oasislabs/ring", default-features = false, features = ["use_heap"], branch = "0.14.0-ekiden" }
serde_cbor = { git = "https://github.com/oasislabs/cbor", tag = "v0.9.0-ekiden1" }
untrusted = "0.6.2"

ekiden-keymanager-api = { path = "../../api", version = "0.2.0-alpha" }
ekiden-keymanager-common = { path = "../../common", version = "0.2.0-alpha" }
34 changes: 34 additions & 0 deletions key-manager/dummy/keygen/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
extern crate ring;
use ring::{rand::SecureRandom, signature::KeyPair};
extern crate serde_cbor;
extern crate untrusted;

extern crate ekiden_keymanager_common;

fn main() {
let rng = ring::rand::SystemRandom::new();

// Generate keystore encryption key.
let mut keystore_encryption_sym: ekiden_keymanager_common::StateKeyType = [0; 64];
rng.fill(&mut keystore_encryption_sym).unwrap();
println!("keystore encryption {:?}", &keystore_encryption_sym[..]);

// Generate signing key.
let signing_pkcs8_doc = ring::signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap();
println!("signing pkcs8 {:?}", signing_pkcs8_doc.as_ref());
let signing_pair = ring::signature::Ed25519KeyPair::from_pkcs8(untrusted::Input::from(
signing_pkcs8_doc.as_ref(),
))
.unwrap();
let signing_public = signing_pair.public_key();
println!("signing public {:?}", signing_public.as_ref());

let keys = ekiden_keymanager_common::DummyInternalKeys {
keystore_encryption_key: keystore_encryption_sym,
signing_key: signing_pkcs8_doc.as_ref().to_owned(),
};
println!(
"serialized InternalKeys {:?}",
serde_cbor::to_vec(&keys).unwrap().as_slice()
);
}
1 change: 1 addition & 0 deletions key-manager/dummy/untrusted/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ repository = "https://github.com/oasislabs/ekiden"
[dependencies]
ekiden-common = { path = "../../../common", version = "0.2.0-alpha" }
ekiden-core = { path = "../../../core/common", version = "0.2.0-alpha" }
ekiden-keymanager-api = { path = "../../api", version = "0.2.0-alpha" }
ekiden-untrusted = { path = "../../../core/untrusted", version = "0.2.0-alpha" }
ekiden-db-trusted = { path = "../../../db/trusted", version = "0.2.0-alpha" }
ekiden-tools = { path = "../../../tools", version = "0.2.0-alpha" }
Expand Down
46 changes: 43 additions & 3 deletions key-manager/dummy/untrusted/src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{
borrow::Borrow,
fmt::Write,
io::Read,
ops::Deref,
path::{Path, PathBuf},
sync::{
Expand Down Expand Up @@ -61,6 +62,8 @@ pub struct BackendConfiguration {
pub storage_backend: Arc<StorageBackend>,
/// Filesystem storage path. Used to locate the roothash db.
pub root_hash_path: PathBuf,
/// Path to internal keys if not using the unsecret testing keys.
pub internal_keys_path: Option<PathBuf>,
}

/// Key manager worker which executes commands in secure enclaves.
Expand All @@ -79,15 +82,27 @@ impl KeyManagerInner {
let (command_sender, command_receiver) = channel();
thread::spawn(move || {
// Question: when is enclave destroyed?
KeyManagerEnclave::new(
let mut enclave = KeyManagerEnclave::new(
&config.enclave_filename,
config.ias,
config.saved_identity_path,
config.storage_backend,
config.root_hash_path,
)
.unwrap()
.run(command_receiver);
.unwrap();
if let Some(internal_keys_path) = config.internal_keys_path {
let mut internal_keys_file = std::fs::File::open(internal_keys_path)
.expect("Couldn't open internal keys file");
let mut internal_keys_buf = vec![];
internal_keys_file
.read_to_end(&mut internal_keys_buf)
.expect("Couldn't read internal keys file");
enclave
.enclave
.set_internal_keys(internal_keys_buf.as_slice())
.expect("Couldn't set internal keys");
}
enclave.run(command_receiver);
});

Self {
Expand Down Expand Up @@ -292,3 +307,28 @@ impl KeyManagerEnclave {
}
}
}

extern "C" {
pub fn set_internal_keys(
eid: sgx_types::sgx_enclave_id_t,
internal_keys: *const u8,
internal_keys_length: usize,
) -> sgx_types::sgx_status_t;
}

trait EnclaveDummyKeymanager {
/// ECALL, see edl
fn set_internal_keys(&self, internal_keys: &[u8]) -> Result<()>;
}

impl EnclaveDummyKeymanager for Enclave {
fn set_internal_keys(&self, internal_keys: &[u8]) -> Result<()> {
let result = unsafe {
set_internal_keys(self.get_id(), internal_keys.as_ptr(), internal_keys.len())
};
if result != sgx_types::sgx_status_t::SGX_SUCCESS {
return Err(Error::new(format!("set_internal_keys: {}", result)));
}
Ok(())
}
}
1 change: 1 addition & 0 deletions key-manager/dummy/untrusted/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern crate log;
extern crate ekiden_common;
extern crate ekiden_core;
extern crate ekiden_db_trusted;
extern crate ekiden_keymanager_api;
extern crate ekiden_rpc_api;
extern crate ekiden_storage_base;
extern crate ekiden_tools;
Expand Down
2 changes: 1 addition & 1 deletion key-manager/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ thread_local = "0.3.5"

[build-dependencies]
ekiden-tools = { path = "../../tools", version = "0.2.0-alpha" }
ekiden-edl = { path = "../../core/edl", version = "0.2.0-alpha" }
ekiden-keymanager-edl = { path = "../dummy/edl", version = "0.2.0-alpha" }

[[bin]]
name = "ekiden-keymanager-test-client"
Expand Down
4 changes: 2 additions & 2 deletions key-manager/node/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
extern crate ekiden_edl;
extern crate ekiden_keymanager_edl;
extern crate ekiden_tools;

fn main() {
ekiden_tools::build_untrusted(ekiden_edl::get_edls().unwrap());
ekiden_tools::build_untrusted(ekiden_keymanager_edl::get_edls().unwrap());
}
7 changes: 7 additions & 0 deletions key-manager/node/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ fn main() {
.default_value("km-tls-key.pem")
.required(true)
)
.arg(
Arg::with_name("internal-keys")
.long("internal-keys")
.takes_value(true)
.help("Path to internal keys file. Uses built-in unsecret keys if not set")
)
.arg(
Arg::with_name("storage-path")
.long("storage-path")
Expand Down Expand Up @@ -127,6 +133,7 @@ fn main() {
forwarded_rpc_timeout: None,
storage_backend: storage_backend,
root_hash_path: root_hash_path,
internal_keys_path: matches.value_of("internal-keys").map(PathBuf::from),
}
},
environment: environment.grpc(),
Expand Down

0 comments on commit a95bc5b

Please sign in to comment.