oasis_core_runtime/consensus/
keymanager.rs1use std::{collections::HashMap, sync::Arc};
2
3use anyhow::Result;
4use thiserror::Error;
5
6use crate::common::{
7    crypto::{
8        signature::{Signature, SignatureBundle, Signer},
9        x25519,
10    },
11    namespace::Namespace,
12    sgx::EnclaveIdentity,
13};
14
15use super::beacon::EpochTime;
16
17pub mod churp;
18
19const POLICY_SIGNATURE_CONTEXT: &[u8] = b"oasis-core/keymanager: policy";
21
22const ENCRYPTED_MASTER_SECRET_SIGNATURE_CONTEXT: &[u8] =
24    b"oasis-core/keymanager: encrypted master secret";
25
26const ENCRYPTED_EPHEMERAL_SECRET_SIGNATURE_CONTEXT: &[u8] =
28    b"oasis-core/keymanager: encrypted ephemeral secret";
29
30#[derive(Error, Debug)]
32pub enum Error {
33    #[error("invalid signature")]
34    InvalidSignature,
35}
36
37#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
39pub struct PolicySGX {
40    pub serial: u32,
41    pub id: Namespace,
42    pub enclaves: HashMap<EnclaveIdentity, EnclavePolicySGX>,
43    #[cbor(optional)]
44    pub master_secret_rotation_interval: EpochTime,
45    #[cbor(optional)]
46    pub max_ephemeral_secret_age: EpochTime,
47}
48
49#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
51pub struct EnclavePolicySGX {
52    pub may_query: HashMap<Namespace, Vec<EnclaveIdentity>>,
55
56    pub may_replicate: Vec<EnclaveIdentity>,
61}
62
63#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
65pub struct SignedPolicySGX {
66    pub policy: PolicySGX,
67    pub signatures: Vec<SignatureBundle>,
68}
69
70impl SignedPolicySGX {
71    pub fn verify(&self) -> Result<&PolicySGX> {
73        let raw_policy = cbor::to_vec(self.policy.clone());
74        for sig in &self.signatures {
75            sig.signature
76                .verify(&sig.public_key, POLICY_SIGNATURE_CONTEXT, &raw_policy)
77                .map_err(|_| Error::InvalidSignature)?;
78        }
79
80        Ok(&self.policy)
81    }
82}
83
84#[derive(Clone, Default, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
86pub struct EncryptedSecret {
87    pub checksum: Vec<u8>,
89    pub pub_key: x25519::PublicKey,
91    pub ciphertexts: HashMap<x25519::PublicKey, Vec<u8>>,
93}
94
95#[derive(Clone, Default, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
97pub struct EncryptedMasterSecret {
98    pub runtime_id: Namespace,
100    pub generation: u64,
102    pub epoch: EpochTime,
104    pub secret: EncryptedSecret,
106}
107
108#[derive(Clone, Default, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
110pub struct EncryptedEphemeralSecret {
111    pub runtime_id: Namespace,
113    pub epoch: EpochTime,
115    pub secret: EncryptedSecret,
117}
118
119#[derive(Clone, Default, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
121pub struct SignedEncryptedMasterSecret {
122    pub secret: EncryptedMasterSecret,
124    pub signature: Signature,
126}
127
128impl SignedEncryptedMasterSecret {
129    pub fn new(secret: EncryptedMasterSecret, signer: &Arc<dyn Signer>) -> Result<Self> {
130        let signature = signer.sign(
131            ENCRYPTED_MASTER_SECRET_SIGNATURE_CONTEXT,
132            &cbor::to_vec(secret.clone()),
133        )?;
134        Ok(Self { secret, signature })
135    }
136}
137
138#[derive(Clone, Default, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
140pub struct SignedEncryptedEphemeralSecret {
141    pub secret: EncryptedEphemeralSecret,
143    pub signature: Signature,
145}
146
147impl SignedEncryptedEphemeralSecret {
148    pub fn new(secret: EncryptedEphemeralSecret, signer: &Arc<dyn Signer>) -> Result<Self> {
149        let signature = signer.sign(
150            ENCRYPTED_EPHEMERAL_SECRET_SIGNATURE_CONTEXT,
151            &cbor::to_vec(secret.clone()),
152        )?;
153        Ok(Self { secret, signature })
154    }
155}