|
@@ -9,10 +9,12 @@ pub mod crypto;
|
|
|
pub mod drop_trigger;
|
|
|
pub mod error;
|
|
|
pub mod log;
|
|
|
+mod readcap_dict;
|
|
|
pub mod sectored_buf;
|
|
|
#[cfg(test)]
|
|
|
mod test_helpers;
|
|
|
mod trailered;
|
|
|
+use readcap_dict::ReadcapDict;
|
|
|
|
|
|
#[macro_use]
|
|
|
extern crate static_assertions;
|
|
@@ -43,7 +45,7 @@ use strum_macros::{Display, EnumDiscriminants, FromRepr};
|
|
|
use accessor::Accessor;
|
|
|
pub use block_path::{BlockPath, BlockPathError};
|
|
|
use crypto::{
|
|
|
- AsymKeyPub, Ciphertext, ConcretePub, Creds, Decrypter, DecrypterExt, Encrypter, EncrypterExt,
|
|
|
+ AsymKeyPub, Ciphertext, ConcretePub, Creds, CredsPub, Decrypter, DecrypterExt, EncrypterExt,
|
|
|
HashKind, MerkleStream, SecretStream, Sign, Signature, Signer, SymKey, SymKeyKind, VarHash,
|
|
|
};
|
|
|
use error::{BoxInIoErr, BtErr};
|
|
@@ -667,7 +669,7 @@ pub struct BlockMetaBody {
|
|
|
/// A copy of the block key encrypted using this block's parent's key. If this is None, then
|
|
|
/// this block is not encrypted.
|
|
|
inherit: Option<Ciphertext<SymKey>>,
|
|
|
- readcaps: BTreeMap<Principal, Ciphertext<SymKey>>,
|
|
|
+ readcaps: ReadcapDict,
|
|
|
writecap: Option<Writecap>,
|
|
|
/// A hash which provides integrity for the contents of the block body.
|
|
|
integrity: Option<VarHash>,
|
|
@@ -689,34 +691,22 @@ pub struct BlockMetaBody {
|
|
|
}
|
|
|
|
|
|
impl BlockMetaBody {
|
|
|
- fn new<C: Creds>(creds: &C) -> Result<BlockMetaBody> {
|
|
|
+ fn new<C: Creds>(creds: C) -> Result<BlockMetaBody> {
|
|
|
let block_key = SymKey::generate(SymKeyKind::default())?;
|
|
|
- let mut readcaps = BTreeMap::new();
|
|
|
- readcaps.insert(creds.principal(), creds.ser_encrypt(&block_key)?);
|
|
|
let secrets = BlockMetaSecrets::default();
|
|
|
- Ok(BlockMetaBody {
|
|
|
+ let mut body = BlockMetaBody {
|
|
|
path: BlockPath::default(),
|
|
|
inherit: None,
|
|
|
- readcaps,
|
|
|
+ readcaps: ReadcapDict::new()?,
|
|
|
writecap: creds.writecap().map(|e| e.to_owned()),
|
|
|
integrity: None,
|
|
|
signing_key: creds.public_sign().to_owned(),
|
|
|
secrets: block_key.ser_encrypt(&secrets)?,
|
|
|
block_key: Some(block_key),
|
|
|
secrets_struct: Some(secrets),
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- pub fn unlock_block_key<C: Decrypter + Principaled>(&mut self, creds: &C) -> Result<()> {
|
|
|
- if self.block_key.is_some() {
|
|
|
- return Ok(());
|
|
|
- }
|
|
|
- let readcap = self
|
|
|
- .readcaps
|
|
|
- .get(&creds.principal())
|
|
|
- .ok_or(crypto::Error::NoReadCap)?;
|
|
|
- self.block_key = Some(creds.ser_decrypt(readcap)?);
|
|
|
- Ok(())
|
|
|
+ };
|
|
|
+ body.add_readcap_for(creds)?;
|
|
|
+ Ok(body)
|
|
|
}
|
|
|
|
|
|
/// Uses the given symmetric key to decrypt the `inherit` field. If this field is `None`, or if
|
|
@@ -769,6 +759,10 @@ impl BlockMetaBody {
|
|
|
.ok_or_else(|| bterr!(BlockError::NoBlockKey))
|
|
|
}
|
|
|
|
|
|
+ pub fn mut_block_key(&mut self) -> &mut Option<SymKey> {
|
|
|
+ &mut self.block_key
|
|
|
+ }
|
|
|
+
|
|
|
pub fn block_id(&self) -> Result<&BlockId> {
|
|
|
let secrets = self.secrets()?;
|
|
|
Ok(secrets.block_id())
|
|
@@ -779,21 +773,17 @@ impl BlockMetaBody {
|
|
|
}
|
|
|
|
|
|
pub fn use_readcap_for<C: Creds>(&mut self, creds: &C) -> Result<&SymKey> {
|
|
|
- let owner = creds.principal();
|
|
|
- let readcap = self.readcaps.get(&owner).ok_or(crypto::Error::NoReadCap)?;
|
|
|
- let block_key = creds.ser_decrypt(readcap)?;
|
|
|
+ let block_key = self.readcaps.get(creds)?;
|
|
|
self.block_key = Some(block_key);
|
|
|
self.block_key()
|
|
|
}
|
|
|
|
|
|
- pub fn mut_block_key(&mut self) -> &mut Option<SymKey> {
|
|
|
- &mut self.block_key
|
|
|
- }
|
|
|
-
|
|
|
- pub fn add_readcap_for<E: Encrypter>(&mut self, owner: Principal, key: &E) -> Result<()> {
|
|
|
- let block_key = self.block_key()?;
|
|
|
- self.readcaps.insert(owner, key.ser_encrypt(block_key)?);
|
|
|
- Ok(())
|
|
|
+ pub fn add_readcap_for<C: CredsPub>(&mut self, creds: C) -> Result<()> {
|
|
|
+ let block_key = self
|
|
|
+ .block_key
|
|
|
+ .as_ref()
|
|
|
+ .ok_or_else(|| bterr!(BlockError::NoBlockKey))?;
|
|
|
+ self.readcaps.set(creds, block_key)
|
|
|
}
|
|
|
|
|
|
pub fn path(&self) -> &BlockPath {
|
|
@@ -882,7 +872,7 @@ impl<T: ReadAt + Sectored + Size, C: Creds> BlockStream<T, C> {
|
|
|
if let Some(parent_key) = parent_key {
|
|
|
meta.body.inherit = Some(parent_key.ser_encrypt(meta.body.block_key()?)?);
|
|
|
} else {
|
|
|
- meta.body.add_readcap_for(creds.principal(), &creds)?;
|
|
|
+ meta.body.add_readcap_for(&creds)?;
|
|
|
}
|
|
|
meta.body.writecap = Some(
|
|
|
creds
|
|
@@ -1507,7 +1497,7 @@ mod tests {
|
|
|
};
|
|
|
|
|
|
let mut body = from_vec::<BlockMetaBody>(&vec).expect("from_vec failed");
|
|
|
- body.unlock_block_key(&creds)
|
|
|
+ body.use_readcap_for(&creds)
|
|
|
.expect("unlock_block_key failed");
|
|
|
let actual_uid = body
|
|
|
.access_secrets(|secrets| Ok(secrets.uid))
|
|
@@ -1779,7 +1769,7 @@ mod tests {
|
|
|
let mut block = case.open_new(path.clone());
|
|
|
block
|
|
|
.mut_meta_body()
|
|
|
- .add_readcap_for(app_creds.principal(), &app_creds)
|
|
|
+ .add_readcap_for(&app_creds)
|
|
|
.expect("failed to add readcap");
|
|
|
block.write(&EXPECTED[..MID]).expect("first write failed");
|
|
|
block.flush().expect("first flush failed");
|