-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
459 additions
and
321 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Flexible key manager policy signers | ||
|
||
The key manager runtime has been split into multiple crates to make its code | ||
reusable. It is now possible for others to write their own key managers that | ||
use a different set of trusted policy signers. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
[package] | ||
name = "oasis-core-keymanager-api-common" | ||
version = "0.3.0-alpha" | ||
authors = ["Oasis Labs Inc. <[email protected]>"] | ||
|
||
[dependencies] | ||
base64 = "0.10.1" | ||
oasis-core-runtime = { path = "../runtime" } | ||
serde = "1.0.71" | ||
serde_derive = "1.0" | ||
serde_bytes = "~0.10" | ||
rustc-hex = "2.0.1" | ||
failure = "0.1.5" | ||
lazy_static = "1.3.0" | ||
x25519-dalek = "0.5.1" | ||
rand = "0.6.5" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
use std::collections::{HashMap, HashSet}; | ||
|
||
use base64; | ||
use failure::Fail; | ||
use rand::{rngs::OsRng, Rng}; | ||
use serde_derive::{Deserialize, Serialize}; | ||
use x25519_dalek; | ||
|
||
use oasis_core_runtime::{ | ||
common::{ | ||
crypto::signature::{PublicKey as OasisPublicKey, Signature, SignatureBundle}, | ||
runtime::RuntimeId, | ||
sgx::avr::EnclaveIdentity, | ||
}, | ||
impl_bytes, | ||
}; | ||
|
||
impl_bytes!(ContractId, 32, "A 256-bit contract identifier."); | ||
impl_bytes!(PrivateKey, 32, "A private key."); | ||
impl_bytes!(PublicKey, 32, "A public key."); | ||
impl_bytes!(StateKey, 32, "A state key."); | ||
impl_bytes!(MasterSecret, 32, "A 256 bit master secret."); | ||
|
||
/// Key manager initialization request. | ||
#[derive(Clone, Serialize, Deserialize)] | ||
pub struct InitRequest { | ||
/// Checksum for validating replication. | ||
#[serde(with = "serde_bytes")] | ||
pub checksum: Vec<u8>, | ||
/// Policy for queries/replication. | ||
#[serde(with = "serde_bytes")] | ||
pub policy: Vec<u8>, | ||
/// True iff the enclave may generate a new master secret. | ||
pub may_generate: bool, | ||
} | ||
|
||
/// Key manager initialization response. | ||
#[derive(Clone, Serialize, Deserialize)] | ||
pub struct InitResponse { | ||
/// True iff the key manager thinks it's running in a secure mode. | ||
pub is_secure: bool, | ||
/// Checksum for validating replication. | ||
#[serde(with = "serde_bytes")] | ||
pub checksum: Vec<u8>, | ||
/// Checksum for identifying policy. | ||
#[serde(with = "serde_bytes")] | ||
pub policy_checksum: Vec<u8>, | ||
} | ||
|
||
/// Context used for the init response signature. | ||
pub const INIT_RESPONSE_CONTEXT: &'static [u8] = b"oasis-core/keymanager: init response"; | ||
|
||
/// Signed InitResponse. | ||
#[derive(Clone, Serialize, Deserialize)] | ||
pub struct SignedInitResponse { | ||
/// InitResponse. | ||
pub init_response: InitResponse, | ||
/// Sign(init_response). | ||
pub signature: Signature, | ||
} | ||
|
||
/// Key manager replication request. | ||
#[derive(Clone, Serialize, Deserialize)] | ||
pub struct ReplicateRequest { | ||
// Empty. | ||
} | ||
|
||
/// Key manager replication response. | ||
#[derive(Clone, Serialize, Deserialize)] | ||
pub struct ReplicateResponse { | ||
pub master_secret: MasterSecret, | ||
} | ||
|
||
/// Request runtime/contract id tuple. | ||
#[derive(Clone, Serialize, Deserialize)] | ||
pub struct RequestIds { | ||
/// Runtime ID. | ||
pub runtime_id: RuntimeId, | ||
/// Contract ID. | ||
pub contract_id: ContractId, | ||
} | ||
|
||
impl RequestIds { | ||
pub fn new(runtime_id: RuntimeId, contract_id: ContractId) -> Self { | ||
Self { | ||
runtime_id, | ||
contract_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 | ||
} | ||
} | ||
|
||
/// Keys for a contract. | ||
#[derive(Clone, Serialize, Deserialize)] | ||
pub struct ContractKey { | ||
/// Input key pair (pk, sk) | ||
pub input_keypair: InputKeyPair, | ||
/// State encryption key | ||
pub state_key: StateKey, | ||
/// Checksum of the key manager state. | ||
#[serde(with = "serde_bytes")] | ||
pub checksum: Vec<u8>, | ||
} | ||
|
||
impl ContractKey { | ||
/// Generate a new random key (for testing). | ||
pub fn generate_mock() -> Self { | ||
let mut rng = OsRng::new().unwrap(); | ||
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); | ||
|
||
ContractKey::new( | ||
PublicKey(*pk.as_bytes()), | ||
PrivateKey(sk.to_bytes()), | ||
state_key, | ||
vec![], | ||
) | ||
} | ||
|
||
/// Create a set of `ContractKey`. | ||
pub fn new(pk: PublicKey, sk: PrivateKey, k: StateKey, sum: Vec<u8>) -> Self { | ||
Self { | ||
input_keypair: InputKeyPair::new(pk, sk), | ||
state_key: k, | ||
checksum: sum, | ||
} | ||
} | ||
|
||
/// Create a set of `ContractKey` with only the public key. | ||
pub fn from_public_key(k: PublicKey, sum: Vec<u8>) -> Self { | ||
Self { | ||
input_keypair: InputKeyPair::new(k, PrivateKey::default()), | ||
state_key: StateKey::default(), | ||
checksum: sum, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Clone, Serialize, Deserialize)] | ||
pub struct InputKeyPair { | ||
/// Pk | ||
pk: PublicKey, | ||
/// sk | ||
sk: PrivateKey, | ||
} | ||
|
||
impl InputKeyPair { | ||
pub fn new(pk: PublicKey, sk: PrivateKey) -> Self { | ||
Self { pk, sk } | ||
} | ||
|
||
pub fn get_pk(&self) -> PublicKey { | ||
self.pk | ||
} | ||
|
||
pub fn get_sk(&self) -> PrivateKey { | ||
self.sk | ||
} | ||
} | ||
|
||
/// Context used for the public key signature. | ||
pub const PUBLIC_KEY_CONTEXT: [u8; 8] = *b"EkKmPubK"; | ||
|
||
/// Signed public key. | ||
#[derive(Clone, Debug, Serialize, Deserialize)] | ||
pub struct SignedPublicKey { | ||
/// Public key. | ||
pub key: PublicKey, | ||
/// Checksum of the key manager state. | ||
#[serde(with = "serde_bytes")] | ||
pub checksum: Vec<u8>, | ||
/// Sign(sk, (key || checksum)) from the key manager. | ||
pub signature: Signature, | ||
} | ||
|
||
/// Key manager error. | ||
#[derive(Debug, Fail)] | ||
pub enum KeyManagerError { | ||
#[fail(display = "client session is not authenticated")] | ||
NotAuthenticated, | ||
#[fail(display = "client session authentication is invalid")] | ||
InvalidAuthentication, | ||
#[fail(display = "key manager is not initialized")] | ||
NotInitialized, | ||
#[fail(display = "key manager state corrupted")] | ||
StateCorrupted, | ||
#[fail(display = "key manager replication required")] | ||
ReplicationRequired, | ||
#[fail(display = "policy rollback")] | ||
PolicyRollback, | ||
#[fail(display = "policy alteration, without serial increment")] | ||
PolicyChanged, | ||
#[fail(display = "policy is malformed or invalid")] | ||
PolicyInvalid, | ||
#[fail(display = "policy failed signature verification")] | ||
PolicyInvalidSignature, | ||
#[fail(display = "policy has insufficient signatures")] | ||
PolicyInsufficientSignatures, | ||
} | ||
|
||
/// Key manager access control policy. | ||
#[derive(Clone, Debug, Serialize, Deserialize)] | ||
pub struct PolicySGX { | ||
pub serial: u32, | ||
pub id: RuntimeId, | ||
pub enclaves: HashMap<EnclaveIdentity, EnclavePolicySGX>, | ||
} | ||
|
||
/// Per enclave key manager access control policy. | ||
#[derive(Clone, Debug, Serialize, Deserialize)] | ||
pub struct EnclavePolicySGX { | ||
pub may_query: HashMap<RuntimeId, Vec<EnclaveIdentity>>, | ||
pub may_replicate: Vec<EnclaveIdentity>, | ||
} | ||
|
||
/// Signed key manager access control policy. | ||
#[derive(Clone, Debug, Serialize, Deserialize)] | ||
pub struct SignedPolicySGX { | ||
pub policy: PolicySGX, | ||
pub signatures: Vec<SignatureBundle>, | ||
} | ||
|
||
/// Set of trusted key manager policy signing keys. | ||
#[derive(Clone, Debug, Serialize, Deserialize)] | ||
pub struct TrustedPolicySigners { | ||
/// Set of trusted signers. | ||
pub signers: HashSet<OasisPublicKey>, | ||
/// Threshold for determining if enough valid signatures are present. | ||
pub threshold: usize, | ||
} | ||
|
||
impl TrustedPolicySigners { | ||
pub fn new() -> Self { | ||
Self { | ||
signers: HashSet::new(), | ||
threshold: 9001, | ||
} | ||
} | ||
} |
Oops, something went wrong.