use std::{collections::HashMap, sync::Arc};
use anyhow::Result;
use thiserror::Error;
use crate::common::{
crypto::{
signature::{Signature, SignatureBundle, Signer},
x25519,
},
namespace::Namespace,
sgx::EnclaveIdentity,
};
use super::beacon::EpochTime;
pub mod churp;
const POLICY_SIGNATURE_CONTEXT: &[u8] = b"oasis-core/keymanager: policy";
const ENCRYPTED_MASTER_SECRET_SIGNATURE_CONTEXT: &[u8] =
b"oasis-core/keymanager: encrypted master secret";
const ENCRYPTED_EPHEMERAL_SECRET_SIGNATURE_CONTEXT: &[u8] =
b"oasis-core/keymanager: encrypted ephemeral secret";
#[derive(Error, Debug)]
pub enum Error {
#[error("invalid signature")]
InvalidSignature,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct PolicySGX {
pub serial: u32,
pub id: Namespace,
pub enclaves: HashMap<EnclaveIdentity, EnclavePolicySGX>,
#[cbor(optional)]
pub master_secret_rotation_interval: EpochTime,
#[cbor(optional)]
pub max_ephemeral_secret_age: EpochTime,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct EnclavePolicySGX {
pub may_query: HashMap<Namespace, Vec<EnclaveIdentity>>,
pub may_replicate: Vec<EnclaveIdentity>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct SignedPolicySGX {
pub policy: PolicySGX,
pub signatures: Vec<SignatureBundle>,
}
impl SignedPolicySGX {
pub fn verify(&self) -> Result<&PolicySGX> {
let raw_policy = cbor::to_vec(self.policy.clone());
for sig in &self.signatures {
sig.signature
.verify(&sig.public_key, POLICY_SIGNATURE_CONTEXT, &raw_policy)
.map_err(|_| Error::InvalidSignature)?;
}
Ok(&self.policy)
}
}
#[derive(Clone, Default, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct EncryptedSecret {
pub checksum: Vec<u8>,
pub pub_key: x25519::PublicKey,
pub ciphertexts: HashMap<x25519::PublicKey, Vec<u8>>,
}
#[derive(Clone, Default, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct EncryptedMasterSecret {
pub runtime_id: Namespace,
pub generation: u64,
pub epoch: EpochTime,
pub secret: EncryptedSecret,
}
#[derive(Clone, Default, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct EncryptedEphemeralSecret {
pub runtime_id: Namespace,
pub epoch: EpochTime,
pub secret: EncryptedSecret,
}
#[derive(Clone, Default, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct SignedEncryptedMasterSecret {
pub secret: EncryptedMasterSecret,
pub signature: Signature,
}
impl SignedEncryptedMasterSecret {
pub fn new(secret: EncryptedMasterSecret, signer: &Arc<dyn Signer>) -> Result<Self> {
let signature = signer.sign(
ENCRYPTED_MASTER_SECRET_SIGNATURE_CONTEXT,
&cbor::to_vec(secret.clone()),
)?;
Ok(Self { secret, signature })
}
}
#[derive(Clone, Default, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct SignedEncryptedEphemeralSecret {
pub secret: EncryptedEphemeralSecret,
pub signature: Signature,
}
impl SignedEncryptedEphemeralSecret {
pub fn new(secret: EncryptedEphemeralSecret, signer: &Arc<dyn Signer>) -> Result<Self> {
let signature = signer.sign(
ENCRYPTED_EPHEMERAL_SECRET_SIGNATURE_CONTEXT,
&cbor::to_vec(secret.clone()),
)?;
Ok(Self { secret, signature })
}
}