Skip to content

Commit 0ff844e

Browse files
authored
Merge pull request #6298 from oasisprotocol/peternose/trivial/km-policy-storage
keymanager/src/policy: Stop saving policy locally
2 parents 26b367e + 3962424 commit 0ff844e

3 files changed

Lines changed: 49 additions & 100 deletions

File tree

.changelog/6298.trivial.md

Whitespace-only changes.

keymanager/src/policy/cached.rs

Lines changed: 48 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,11 @@ use std::{
77

88
use anyhow::Result;
99
use lazy_static::lazy_static;
10-
use sgx_isa::Keypolicy;
1110
use tiny_keccak::{Hasher, Sha3};
1211

1312
use oasis_core_runtime::{
14-
common::{
15-
namespace::Namespace,
16-
sgx::{
17-
seal::{seal, unseal},
18-
EnclaveIdentity,
19-
},
20-
},
21-
consensus::{beacon::EpochTime, keymanager::SignedPolicySGX},
22-
storage::KeyValue,
13+
common::{namespace::Namespace, sgx::EnclaveIdentity},
14+
consensus::keymanager::SignedPolicySGX,
2315
};
2416

2517
use crate::api::KeyManagerError;
@@ -30,9 +22,6 @@ lazy_static! {
3022
static ref POLICY: Policy = Policy::new();
3123
}
3224

33-
const POLICY_STORAGE_KEY: &[u8] = b"keymanager_policy";
34-
const POLICY_SEAL_CONTEXT: &[u8] = b"oasis-core/keymanager: policy seal";
35-
3625
/// Policy, which manages the key manager policy.
3726
pub struct Policy {
3827
inner: RwLock<Inner>,
@@ -66,49 +55,40 @@ impl Policy {
6655
///
6756
/// The policy is presumed trustworthy, so it's up to the caller to verify it against
6857
/// the consensus layer state. Empty polices are allowed only in unsafe builds.
69-
pub fn init(&self, storage: &dyn KeyValue, policy: Option<SignedPolicySGX>) -> Result<Vec<u8>> {
58+
pub fn init(&self, policy: Option<SignedPolicySGX>) -> Result<Vec<u8>> {
7059
// If this is an insecure build, don't bother trying to apply any policy.
7160
if policy.is_none() && Self::unsafe_skip() {
7261
return Ok(vec![]);
7362
}
7463

7564
// Cache the new policy.
7665
let policy = policy.ok_or(KeyManagerError::PolicyRequired)?;
77-
let raw_policy = cbor::to_vec(policy.clone());
78-
let new_policy = CachedPolicy::parse(policy, &raw_policy)?;
66+
let new_policy = CachedPolicy::parse(policy)?;
7967

8068
// Lock as late as possible.
8169
let mut inner = self.inner.write().unwrap();
8270

83-
// If there is no existing policy, attempt to load from local storage.
84-
let old_policy = inner
85-
.policy
86-
.as_ref()
87-
.cloned()
88-
.unwrap_or_else(|| Self::load_policy(storage).unwrap_or_default());
89-
9071
// Compare the new serial number with the old serial number, ensure
9172
// it is greater.
92-
match old_policy.serial.cmp(&new_policy.serial) {
93-
Ordering::Greater => Err(KeyManagerError::PolicyRollback.into()),
94-
Ordering::Equal if old_policy.checksum != new_policy.checksum => {
95-
// Policy should be identical.
96-
Err(KeyManagerError::PolicyChanged.into())
97-
}
98-
Ordering::Equal => {
99-
inner.policy = Some(old_policy.clone());
100-
Ok(old_policy.checksum)
101-
}
102-
Ordering::Less => {
103-
// Persist then apply the new policy.
104-
Self::save_raw_policy(storage, &raw_policy);
105-
let new_checksum = new_policy.checksum.clone();
106-
inner.policy = Some(new_policy);
107-
108-
// Return the checksum of the newly applied policy.
109-
Ok(new_checksum)
73+
if let Some(old_policy) = inner.policy.as_ref() {
74+
match old_policy.serial.cmp(&new_policy.serial) {
75+
Ordering::Greater => return Err(KeyManagerError::PolicyRollback.into()),
76+
Ordering::Equal => {
77+
if old_policy.checksum != new_policy.checksum {
78+
// Policy should be identical.
79+
return Err(KeyManagerError::PolicyChanged.into());
80+
}
81+
return Ok(new_policy.checksum);
82+
}
83+
Ordering::Less => {}
11084
}
111-
}
85+
};
86+
87+
// Return the checksum of the newly applied policy.
88+
let new_checksum = new_policy.checksum.clone();
89+
inner.policy = Some(new_policy);
90+
91+
Ok(new_checksum)
11292
}
11393

11494
/// Check if the MRSIGNER/MRENCLAVE may query keys for the given
@@ -172,82 +152,51 @@ impl Policy {
172152
false => Some(src_set),
173153
}
174154
}
175-
176-
fn load_policy(storage: &dyn KeyValue) -> Option<CachedPolicy> {
177-
let ciphertext = storage.get(POLICY_STORAGE_KEY.to_vec()).unwrap();
178-
179-
unseal(Keypolicy::MRENCLAVE, POLICY_SEAL_CONTEXT, &ciphertext)
180-
.unwrap()
181-
.map(|plaintext| {
182-
// Deserialization failures are fatal, because it is state corruption.
183-
CachedPolicy::parse_raw(&plaintext).expect("failed to deserialize persisted policy")
184-
})
185-
}
186-
187-
fn save_raw_policy(storage: &dyn KeyValue, raw_policy: &[u8]) {
188-
let ciphertext = seal(Keypolicy::MRENCLAVE, POLICY_SEAL_CONTEXT, raw_policy);
189-
190-
// Persist the encrypted policy.
191-
storage
192-
.insert(POLICY_STORAGE_KEY.to_vec(), ciphertext)
193-
.expect("failed to persist policy");
194-
}
195155
}
196156

197157
#[derive(Clone, Default, Debug)]
198158
struct CachedPolicy {
199159
pub checksum: Vec<u8>,
200160
pub serial: u32,
201-
pub runtime_id: Namespace,
202161
pub may_query: HashMap<Namespace, HashSet<EnclaveIdentity>>,
203162
pub may_replicate: HashSet<EnclaveIdentity>,
204163
pub may_replicate_from: HashSet<EnclaveIdentity>,
205-
pub master_secret_rotation_interval: EpochTime,
206-
pub max_ephemeral_secret_age: EpochTime,
207164
}
208165

209166
impl CachedPolicy {
210-
fn parse_raw(raw: &[u8]) -> Result<Self> {
211-
let untrusted_policy: SignedPolicySGX = cbor::from_slice(raw)?;
212-
Self::parse(untrusted_policy, raw)
213-
}
214-
215-
fn parse(untrusted_policy: SignedPolicySGX, raw: &[u8]) -> Result<Self> {
167+
fn parse(untrusted_policy: SignedPolicySGX) -> Result<Self> {
216168
let policy = verify_data_and_trusted_signers(&untrusted_policy)?;
217-
let checksum = Self::checksum_policy(raw);
218-
219-
let mut cached_policy = Self::default();
220-
cached_policy.serial = policy.serial;
221-
cached_policy.runtime_id = policy.id;
222-
cached_policy.checksum = checksum;
223169

224170
// Convert the policy into a cached one.
225-
let enclave_identity = match EnclaveIdentity::current() {
226-
Some(enclave_identity) => enclave_identity,
227-
None => return Ok(cached_policy),
228-
};
229-
let enclave_policy = match policy.enclaves.get(&enclave_identity) {
230-
Some(enclave_policy) => enclave_policy,
231-
None => return Ok(cached_policy), // No policy for the current enclave.
171+
let mut cached_policy = CachedPolicy {
172+
serial: policy.serial,
173+
..Default::default()
232174
};
233-
for (rt_id, ids) in &enclave_policy.may_query {
234-
let mut query_ids = HashSet::new();
235-
for e_id in ids {
236-
query_ids.insert(e_id.clone());
237-
}
238-
cached_policy.may_query.insert(*rt_id, query_ids);
239-
}
240-
for e_id in &enclave_policy.may_replicate {
241-
cached_policy.may_replicate.insert(e_id.clone());
242-
}
243-
for (e_id, other_policy) in &policy.enclaves {
244-
if other_policy.may_replicate.contains(&enclave_identity) {
245-
cached_policy.may_replicate_from.insert(e_id.clone());
175+
176+
if let Some(enclave_identity) = EnclaveIdentity::current() {
177+
if let Some(enclave_policy) = policy.enclaves.get(&enclave_identity) {
178+
for (rt_id, ids) in &enclave_policy.may_query {
179+
let mut query_ids = HashSet::new();
180+
for e_id in ids {
181+
query_ids.insert(e_id.clone());
182+
}
183+
cached_policy.may_query.insert(*rt_id, query_ids);
184+
}
185+
186+
for e_id in &enclave_policy.may_replicate {
187+
cached_policy.may_replicate.insert(e_id.clone());
188+
}
189+
190+
for (e_id, other_policy) in &policy.enclaves {
191+
if other_policy.may_replicate.contains(&enclave_identity) {
192+
cached_policy.may_replicate_from.insert(e_id.clone());
193+
}
194+
}
246195
}
247196
}
248197

249-
cached_policy.master_secret_rotation_interval = policy.master_secret_rotation_interval;
250-
cached_policy.max_ephemeral_secret_age = policy.max_ephemeral_secret_age;
198+
let raw = cbor::to_vec(untrusted_policy);
199+
cached_policy.checksum = Self::checksum_policy(&raw);
251200

252201
Ok(cached_policy)
253202
}

keymanager/src/runtime/secrets.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl Secrets {
117117

118118
// Empty policies are allowed only in unsafe builds.
119119
let policy = Policy::global();
120-
let policy_checksum = policy.init(&self.storage, status.policy)?;
120+
let policy_checksum = policy.init(status.policy)?;
121121

122122
// Initialize or update the KDF.
123123
let generation = status.generation;

0 commit comments

Comments
 (0)