lib.rs 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271
  1. #![allow(incomplete_features)]
  2. #![feature(trait_upcasting)]
  3. mod block_path;
  4. pub use block_path::{BlockPath, BlockPathError};
  5. pub mod blocktree;
  6. /// Code which enables cryptographic operations.
  7. pub mod crypto;
  8. pub mod msg;
  9. mod sectored_buf;
  10. mod trailered;
  11. #[cfg(feature = "testing")]
  12. pub mod test_helpers;
  13. #[macro_use]
  14. extern crate static_assertions;
  15. #[cfg(feature = "testing")]
  16. #[macro_use]
  17. extern crate lazy_static;
  18. use brotli::{CompressorWriter, Decompressor};
  19. use crypto::{
  20. AsymKeyPub, Ciphertext, Creds, Decrypter, DecrypterExt, Encrypter, EncrypterExt, HashKind,
  21. MerkleStream, PublicCreds, SecretStream, Sign, Signature, Signer, SymKey, SymKeyKind, VarHash,
  22. };
  23. use fuse_backend_rs::{
  24. abi::fuse_abi::{stat64, Attr},
  25. file_traits::FileReadWriteVolatile,
  26. };
  27. use log::error;
  28. use sectored_buf::SectoredBuf;
  29. use serde::{Deserialize, Serialize};
  30. use serde_big_array::BigArray;
  31. use std::{
  32. collections::{btree_map, hash_map::DefaultHasher, BTreeMap, HashMap},
  33. convert::{Infallible, TryFrom},
  34. fmt::{self, Display, Formatter},
  35. hash::{Hash as Hashable, Hasher},
  36. io::{self, Read, Seek, SeekFrom, Write},
  37. net::SocketAddr,
  38. ops::{Add, Sub},
  39. sync::PoisonError,
  40. time::{Duration, SystemTime},
  41. };
  42. use trailered::Trailered;
  43. #[derive(Debug)]
  44. pub enum Error {
  45. MissingWritecap,
  46. Io(std::io::Error),
  47. Serde(btserde::Error),
  48. Crypto(crypto::Error),
  49. IncorrectSize { expected: usize, actual: usize },
  50. NoBlockKey,
  51. Custom(Box<dyn std::fmt::Debug + Send + Sync>),
  52. }
  53. impl Error {
  54. fn custom<E: std::fmt::Debug + Send + Sync + 'static>(err: E) -> Error {
  55. Error::Custom(Box::new(err))
  56. }
  57. }
  58. impl Display for Error {
  59. fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  60. match self {
  61. Error::MissingWritecap => write!(f, "missing writecap"),
  62. Error::Io(err) => err.fmt(f),
  63. Error::Serde(err) => err.fmt(f),
  64. Error::Crypto(err) => err.fmt(f),
  65. Error::IncorrectSize { expected, actual } => {
  66. write!(f, "incorrect size {actual}, expected {expected}")
  67. }
  68. Error::NoBlockKey => write!(f, "no block key is present"),
  69. Error::Custom(err) => err.fmt(f),
  70. }
  71. }
  72. }
  73. impl std::error::Error for Error {}
  74. impl From<std::io::Error> for Error {
  75. fn from(err: std::io::Error) -> Self {
  76. Error::Io(err)
  77. }
  78. }
  79. impl From<Error> for std::io::Error {
  80. fn from(err: Error) -> Self {
  81. io::Error::new(io::ErrorKind::Other, err)
  82. }
  83. }
  84. impl From<btserde::Error> for Error {
  85. fn from(err: btserde::Error) -> Self {
  86. Error::Serde(err)
  87. }
  88. }
  89. impl From<crypto::Error> for Error {
  90. fn from(err: crypto::Error) -> Self {
  91. Error::Crypto(err)
  92. }
  93. }
  94. impl From<std::num::TryFromIntError> for Error {
  95. fn from(err: std::num::TryFromIntError) -> Self {
  96. Error::custom(err)
  97. }
  98. }
  99. impl<T: std::fmt::Debug> From<PoisonError<T>> for Error {
  100. fn from(err: PoisonError<T>) -> Self {
  101. Error::custom(err.to_string())
  102. }
  103. }
  104. type Result<T> = std::result::Result<T, Error>;
  105. /// TODO: Remove this once the error_chain crate is integrated.
  106. trait BoxInIoErr<T> {
  107. fn box_err(self) -> std::result::Result<T, io::Error>;
  108. }
  109. impl<T, E: std::error::Error + Send + Sync + 'static> BoxInIoErr<T> for std::result::Result<T, E> {
  110. fn box_err(self) -> std::result::Result<T, io::Error> {
  111. self.map_err(|err| io::Error::new(io::ErrorKind::Other, err))
  112. }
  113. }
  114. /// TODO: Remove this once the error_chain crate is integrated.
  115. trait StrInIoErr<T> {
  116. fn str_err(self) -> std::result::Result<T, io::Error>;
  117. }
  118. impl<T, E: Display> StrInIoErr<T> for std::result::Result<T, E> {
  119. fn str_err(self) -> std::result::Result<T, io::Error> {
  120. self.map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))
  121. }
  122. }
  123. /// The default sector size to use for new blocks.
  124. const SECTOR_SZ_DEFAULT: usize = 4096;
  125. /// Trait for types which provide read and write access to blocks.
  126. pub trait Block: Read + Write + Seek + MetaAccess + FileReadWriteVolatile {}
  127. // A trait for streams which only allow reads and writes in fixed sized units called sectors.
  128. pub trait Sectored {
  129. // Returns the size of the sector for this stream.
  130. fn sector_sz(&self) -> usize;
  131. fn assert_sector_sz(&self, actual: usize) -> Result<()> {
  132. let expected = self.sector_sz();
  133. if expected == actual {
  134. Ok(())
  135. } else {
  136. Err(Error::IncorrectSize { expected, actual })
  137. }
  138. }
  139. }
  140. /// A version of the `Write` trait, which allows integrity information to be supplied when flushing.
  141. pub trait WriteInteg: Write {
  142. fn flush_integ(&mut self, integrity: &[u8]) -> io::Result<()>;
  143. }
  144. trait Decompose<T> {
  145. fn into_inner(self) -> T;
  146. }
  147. trait TryCompose<T, U: Decompose<T>> {
  148. type Error;
  149. fn try_compose(self, inner: T) -> std::result::Result<U, Self::Error>;
  150. }
  151. trait Compose<T, U> {
  152. fn compose(self, inner: T) -> U;
  153. }
  154. impl<T, U: Decompose<T>, S: TryCompose<T, U, Error = Infallible>> Compose<T, U> for S {
  155. fn compose(self, inner: T) -> U {
  156. let result = self.try_compose(inner);
  157. // Safety: Infallible has no values, so `result` must be `Ok`.
  158. unsafe { result.unwrap_unchecked() }
  159. }
  160. }
  161. /// Trait for accessing the metadata associated with a block.
  162. pub trait MetaAccess {
  163. fn meta(&self) -> &BlockMeta;
  164. fn mut_meta(&mut self) -> &mut BlockMeta;
  165. fn meta_body(&self) -> &BlockMetaBody {
  166. self.meta().body()
  167. }
  168. fn mut_meta_body(&mut self) -> &mut BlockMetaBody {
  169. self.mut_meta().mut_body()
  170. }
  171. }
  172. /// Extensions to the `Read` trait.
  173. trait ReadExt: Read {
  174. /// Reads repeatedly until one of the following occur:
  175. /// 1. The given buffer is full.
  176. /// 2. A call to `read` returns 0.
  177. /// 3. A call to `read` returns an error.
  178. /// The number of bytes read is returned. If an error is returned, then no bytes were read.
  179. fn fill_buf(&mut self, mut dest: &mut [u8]) -> io::Result<usize> {
  180. let dest_len_start = dest.len();
  181. while !dest.is_empty() {
  182. let byte_ct = match self.read(dest) {
  183. Ok(byte_ct) => byte_ct,
  184. Err(err) => {
  185. if dest_len_start == dest.len() {
  186. return Err(err);
  187. } else {
  188. // We're not allowed to return an error since we've already read from self.
  189. error!("an error occurred in fill_buf: {}", err);
  190. break;
  191. }
  192. }
  193. };
  194. if 0 == byte_ct {
  195. break;
  196. }
  197. dest = &mut dest[byte_ct..];
  198. }
  199. Ok(dest_len_start - dest.len())
  200. }
  201. }
  202. impl<T: Read> ReadExt for T {}
  203. trait HashExt: Hashable {
  204. /// Returns the hash produced by the `DefaultHasher`.
  205. fn default_hash(&self) -> u64 {
  206. let mut hasher = DefaultHasher::new();
  207. self.hash(&mut hasher);
  208. hasher.finish()
  209. }
  210. }
  211. impl<T: Hashable> HashExt for T {}
  212. /// Metadata that is encrypted.
  213. #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Hash)]
  214. pub struct BlockMetaSecrets {
  215. /// The inode number of the file.
  216. inode: u64,
  217. /// Mode of file.
  218. mode: u32,
  219. /// Owner UID of file.
  220. uid: u32,
  221. /// Owner GID of file.
  222. gid: u32,
  223. /// Last access time.
  224. atime: Epoch,
  225. /// Last data modification.
  226. mtime: Epoch,
  227. /// Last status change.
  228. ctime: Epoch,
  229. /// Size of the file in bytes.
  230. size: u64,
  231. /// Number of hard links to the file.
  232. nlink: u32,
  233. /// The sector size used by the block.
  234. sect_sz: u32,
  235. tags: BTreeMap<String, Vec<u8>>,
  236. }
  237. impl BlockMetaSecrets {
  238. pub fn new() -> BlockMetaSecrets {
  239. Self::default()
  240. }
  241. pub fn attr(&self) -> Attr {
  242. self.into()
  243. }
  244. pub fn stat(&self) -> stat64 {
  245. self.attr().into()
  246. }
  247. /// Returns the number of sectors occupied by the block's data.
  248. pub fn sectors(&self) -> u64 {
  249. let sect_sz = self.sect_sz as u64;
  250. if self.size % sect_sz == 0 {
  251. self.size / sect_sz
  252. } else {
  253. self.size / sect_sz + 1
  254. }
  255. }
  256. }
  257. impl Default for BlockMetaSecrets {
  258. fn default() -> Self {
  259. Self {
  260. inode: 0,
  261. mode: 0,
  262. uid: 0,
  263. gid: 0,
  264. atime: Epoch::default(),
  265. mtime: Epoch::default(),
  266. ctime: Epoch::default(),
  267. size: 0,
  268. nlink: 0,
  269. sect_sz: SECTOR_SZ_DEFAULT.try_into().unwrap(),
  270. tags: BTreeMap::new(),
  271. }
  272. }
  273. }
  274. impl From<&BlockMetaSecrets> for Attr {
  275. fn from(value: &BlockMetaSecrets) -> Self {
  276. Attr {
  277. ino: value.inode,
  278. size: value.size,
  279. atime: value.atime.value(),
  280. mtime: value.mtime.value(),
  281. ctime: value.ctime.value(),
  282. atimensec: 0,
  283. mtimensec: 0,
  284. ctimensec: 0,
  285. mode: value.mode,
  286. nlink: value.nlink,
  287. uid: value.uid,
  288. gid: value.gid,
  289. rdev: 0,
  290. blksize: value.sect_sz,
  291. blocks: value.sectors(),
  292. flags: 0,
  293. }
  294. }
  295. }
  296. /// This struct contains all of the metadata fields associated with a block, except for its
  297. /// signature. Since this struct implements `Serialize`, this allows for convenient signature
  298. /// calculations.
  299. #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
  300. pub struct BlockMetaBody {
  301. path: BlockPath,
  302. /// A copy of the block key encrypted using this block's parent's key. If this is None, then
  303. /// this block is not encrypted.
  304. inherit: Option<Ciphertext<SymKey>>,
  305. readcaps: BTreeMap<Principal, Ciphertext<SymKey>>,
  306. writecap: Option<Writecap>,
  307. /// A hash which provides integrity for the contents of the block body.
  308. integrity: Option<VarHash>,
  309. /// The public key that corresponds to the private key used to sign these metadata.
  310. signing_key: AsymKeyPub<Sign>,
  311. /// Additional metadata which is subject to confidentiality protection.
  312. secrets: Ciphertext<BlockMetaSecrets>,
  313. #[serde(skip)]
  314. /// The cleartext block key.
  315. block_key: Option<SymKey>,
  316. #[serde(skip)]
  317. /// The clear text secret metadata.
  318. secrets_struct: Option<BlockMetaSecrets>,
  319. }
  320. impl BlockMetaBody {
  321. fn new<C: Creds>(creds: &C) -> Result<BlockMetaBody> {
  322. let block_key = SymKey::generate(SymKeyKind::default())?;
  323. let mut readcaps = BTreeMap::new();
  324. readcaps.insert(creds.principal(), creds.ser_encrypt(&block_key)?);
  325. Ok(BlockMetaBody {
  326. path: BlockPath::default(),
  327. inherit: None,
  328. readcaps,
  329. writecap: creds.writecap().map(|e| e.to_owned()),
  330. integrity: None,
  331. signing_key: creds.public_sign().to_owned(),
  332. secrets: block_key.ser_encrypt(&BlockMetaSecrets::default())?,
  333. block_key: Some(block_key),
  334. secrets_struct: None,
  335. })
  336. }
  337. pub fn unlock_block_key<C: Creds>(&mut self, creds: &C) -> Result<()> {
  338. if self.block_key.is_some() {
  339. return Ok(());
  340. }
  341. let readcap = self
  342. .readcaps
  343. .get(&creds.principal())
  344. .ok_or(crypto::Error::NoReadCap)?;
  345. self.block_key = Some(creds.ser_decrypt(readcap)?);
  346. Ok(())
  347. }
  348. pub fn access_secrets<T, F: FnOnce(&mut BlockMetaSecrets) -> Result<T>>(
  349. &mut self,
  350. accessor: F,
  351. ) -> Result<T> {
  352. let secrets = match self.secrets_struct.as_mut() {
  353. Some(secrets) => secrets,
  354. None => {
  355. let block_key = self.block_key()?;
  356. self.secrets_struct = Some(block_key.ser_decrypt(&self.secrets)?);
  357. self.secrets_struct.as_mut().unwrap()
  358. }
  359. };
  360. let prev = secrets.default_hash();
  361. let output = accessor(secrets)?;
  362. if prev != secrets.default_hash() {
  363. self.secrets = self
  364. .block_key
  365. .as_ref()
  366. .ok_or(Error::NoBlockKey)?
  367. .ser_encrypt(secrets)?;
  368. }
  369. Ok(output)
  370. }
  371. pub fn secrets(&self) -> Result<&BlockMetaSecrets> {
  372. self.secrets_struct
  373. .as_ref()
  374. .ok_or_else(|| Error::custom("secrets have not been decrypted"))
  375. }
  376. pub fn block_key(&self) -> Result<&SymKey> {
  377. self.block_key.as_ref().ok_or(Error::NoBlockKey)
  378. }
  379. pub fn use_block_key_for<C: Creds>(&mut self, creds: &C) -> Result<&SymKey> {
  380. let readcap = self
  381. .readcaps
  382. .get(&creds.principal())
  383. .ok_or(crypto::Error::NoReadCap)?;
  384. let block_key = creds.ser_decrypt(readcap)?;
  385. self.block_key = Some(block_key);
  386. self.block_key()
  387. }
  388. pub fn mut_block_key(&mut self) -> &mut Option<SymKey> {
  389. &mut self.block_key
  390. }
  391. pub fn integrity(&self) -> Option<&[u8]> {
  392. self.integrity.as_ref().map(|hash| hash.as_slice())
  393. }
  394. pub fn add_readcap_for<E: Encrypter>(&mut self, owner: Principal, key: &E) -> Result<()> {
  395. let block_key = self.block_key()?;
  396. self.readcaps.insert(owner, key.ser_encrypt(block_key)?);
  397. Ok(())
  398. }
  399. pub fn set_path(&mut self, path: BlockPath) {
  400. self.path = path
  401. }
  402. }
  403. /// Signed metadata associated with a block.
  404. #[derive(Serialize, Deserialize)]
  405. pub struct BlockMeta {
  406. body: BlockMetaBody,
  407. sig: Signature,
  408. }
  409. impl BlockMeta {
  410. fn new<C: Creds>(creds: &C) -> Result<BlockMeta> {
  411. let body = BlockMetaBody::new(creds)?;
  412. let sig = Signature::empty(body.signing_key.scheme());
  413. Ok(BlockMeta { body, sig })
  414. }
  415. pub fn body(&self) -> &BlockMetaBody {
  416. self.as_ref()
  417. }
  418. pub fn mut_body(&mut self) -> &mut BlockMetaBody {
  419. self.as_mut()
  420. }
  421. }
  422. impl AsRef<BlockMetaBody> for BlockMeta {
  423. fn as_ref(&self) -> &BlockMetaBody {
  424. &self.body
  425. }
  426. }
  427. impl AsMut<BlockMetaBody> for BlockMeta {
  428. fn as_mut(&mut self) -> &mut BlockMetaBody {
  429. &mut self.body
  430. }
  431. }
  432. struct BlockStream<T, C> {
  433. trailered: Trailered<T, BlockMeta>,
  434. meta: BlockMeta,
  435. meta_body_buf: Vec<u8>,
  436. creds: C,
  437. }
  438. impl<T: Read + Seek, C: Creds> BlockStream<T, C> {
  439. fn new(inner: T, creds: C) -> Result<BlockStream<T, C>> {
  440. let (trailered, meta) = Trailered::<_, BlockMeta>::new(inner)?;
  441. let meta = match meta {
  442. Some(mut meta) => {
  443. meta.assert_valid()?;
  444. // We need to use the writecap and signing_key provided by the current credentials.
  445. meta.body.writecap = creds.writecap().map(|e| e.to_owned());
  446. meta.body.signing_key = creds.public_sign().to_owned();
  447. meta.body.use_block_key_for(&creds)?;
  448. meta
  449. }
  450. None => {
  451. let mut meta = BlockMeta::new(&creds)?;
  452. meta.mut_body().add_readcap_for(creds.principal(), &creds)?;
  453. meta.body.writecap = creds.writecap().map(|e| e.to_owned());
  454. meta
  455. }
  456. };
  457. Ok(BlockStream {
  458. trailered,
  459. meta,
  460. meta_body_buf: Vec::new(),
  461. creds,
  462. })
  463. }
  464. }
  465. impl<T: Write + Seek, C: Signer> Write for BlockStream<T, C> {
  466. fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
  467. self.trailered.write(buf)
  468. }
  469. fn flush(&mut self) -> io::Result<()> {
  470. Err(io::Error::new(
  471. io::ErrorKind::Unsupported,
  472. "flush is not supported, use flush_integ instead",
  473. ))
  474. }
  475. }
  476. impl<T: Write + Seek, C: Signer> WriteInteg for BlockStream<T, C> {
  477. fn flush_integ(&mut self, integrity: &[u8]) -> io::Result<()> {
  478. let meta_body = &mut self.meta.body;
  479. let integ = meta_body.integrity.get_or_insert_with(VarHash::default);
  480. integ.as_mut().copy_from_slice(integrity);
  481. self.meta_body_buf.clear();
  482. self.meta.sig = self
  483. .creds
  484. .ser_sign_into(&meta_body, &mut self.meta_body_buf)?;
  485. self.trailered.flush(&self.meta)?;
  486. Ok(())
  487. }
  488. }
  489. impl<T: Read + Seek, C> Read for BlockStream<T, C> {
  490. fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
  491. self.trailered.read(buf)
  492. }
  493. }
  494. impl<T: Seek, C> Seek for BlockStream<T, C> {
  495. /// Seeks to the given position in the stream. If a position beyond the end of the stream is
  496. /// specified, the the seek will be to the end of the stream.
  497. fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
  498. self.trailered.seek(pos)
  499. }
  500. }
  501. impl<T, C: Decrypter + Principaled> MetaAccess for BlockStream<T, C> {
  502. fn meta(&self) -> &BlockMeta {
  503. &self.meta
  504. }
  505. fn mut_meta(&mut self) -> &mut BlockMeta {
  506. &mut self.meta
  507. }
  508. }
  509. impl<T: FileReadWriteVolatile, C> FileReadWriteVolatile for BlockStream<T, C> {
  510. fn read_volatile(
  511. &mut self,
  512. slice: fuse_backend_rs::file_buf::FileVolatileSlice,
  513. ) -> io::Result<usize> {
  514. self.trailered.read_volatile(slice)
  515. }
  516. fn write_volatile(
  517. &mut self,
  518. slice: fuse_backend_rs::file_buf::FileVolatileSlice,
  519. ) -> io::Result<usize> {
  520. self.trailered.write_volatile(slice)
  521. }
  522. fn read_at_volatile(
  523. &mut self,
  524. slice: fuse_backend_rs::file_buf::FileVolatileSlice,
  525. offset: u64,
  526. ) -> io::Result<usize> {
  527. self.trailered.read_at_volatile(slice, offset)
  528. }
  529. fn write_at_volatile(
  530. &mut self,
  531. slice: fuse_backend_rs::file_buf::FileVolatileSlice,
  532. offset: u64,
  533. ) -> io::Result<usize> {
  534. self.trailered.write_at_volatile(slice, offset)
  535. }
  536. }
  537. impl<T: Read + Write + Seek + MetaAccess + FileReadWriteVolatile, C: Creds> Block
  538. for BlockStream<T, C>
  539. {
  540. }
  541. pub struct BlockOpenOptions<T, C> {
  542. inner: T,
  543. creds: C,
  544. encrypt: bool,
  545. compress: bool,
  546. }
  547. impl BlockOpenOptions<(), ()> {
  548. pub fn new() -> BlockOpenOptions<(), ()> {
  549. BlockOpenOptions {
  550. inner: (),
  551. creds: (),
  552. encrypt: true,
  553. compress: true,
  554. }
  555. }
  556. }
  557. impl<T, C> BlockOpenOptions<T, C> {
  558. pub fn with_inner<U>(self, inner: U) -> BlockOpenOptions<U, C> {
  559. BlockOpenOptions {
  560. inner,
  561. creds: self.creds,
  562. encrypt: self.encrypt,
  563. compress: self.compress,
  564. }
  565. }
  566. pub fn with_creds<D>(self, creds: D) -> BlockOpenOptions<T, D> {
  567. BlockOpenOptions {
  568. inner: self.inner,
  569. creds,
  570. encrypt: self.encrypt,
  571. compress: self.compress,
  572. }
  573. }
  574. pub fn with_encrypt(mut self, encrypt: bool) -> Self {
  575. self.encrypt = encrypt;
  576. self
  577. }
  578. pub fn with_compress(mut self, compress: bool) -> Self {
  579. self.compress = compress;
  580. self
  581. }
  582. }
  583. impl<T: Read + Write + Seek + FileReadWriteVolatile + 'static, C: Creds + 'static>
  584. BlockOpenOptions<T, C>
  585. {
  586. pub fn open(self) -> Result<Box<dyn Block>> {
  587. let stream = BlockStream::new(self.inner, self.creds)?;
  588. let block_key = stream.meta_body().block_key().map(|e| e.to_owned())?;
  589. let mut stream = MerkleStream::new(stream)?;
  590. stream.assert_root_integrity()?;
  591. let sect_sz = stream.sector_sz();
  592. stream.mut_meta_body().access_secrets(|secrets| {
  593. secrets.sect_sz = sect_sz.try_into()?;
  594. Ok(())
  595. })?;
  596. if self.encrypt {
  597. let stream = SecretStream::new(block_key).try_compose(stream)?;
  598. let stream = SectoredBuf::new().try_compose(stream)?;
  599. Ok(Box::new(stream))
  600. } else {
  601. let stream = SectoredBuf::new().try_compose(stream)?;
  602. Ok(Box::new(stream))
  603. }
  604. }
  605. }
  606. impl Default for BlockOpenOptions<(), ()> {
  607. fn default() -> Self {
  608. Self::new()
  609. }
  610. }
  611. impl<T: Write> Decompose<T> for CompressorWriter<T> {
  612. fn into_inner(self) -> T {
  613. self.into_inner()
  614. }
  615. }
  616. impl<T: Read> Decompose<T> for Decompressor<T> {
  617. fn into_inner(self) -> T {
  618. self.into_inner()
  619. }
  620. }
  621. #[derive(Clone)]
  622. pub struct BrotliParams {
  623. buf_sz: usize,
  624. quality: u32,
  625. window_sz: u32,
  626. }
  627. impl BrotliParams {
  628. pub fn new(buf_sz: usize, quality: u32, window_sz: u32) -> BrotliParams {
  629. BrotliParams {
  630. buf_sz,
  631. quality,
  632. window_sz,
  633. }
  634. }
  635. }
  636. impl<T: Write> TryCompose<T, CompressorWriter<T>> for BrotliParams {
  637. type Error = Error;
  638. fn try_compose(self, inner: T) -> Result<CompressorWriter<T>> {
  639. Ok(CompressorWriter::new(
  640. inner,
  641. self.buf_sz,
  642. self.quality,
  643. self.window_sz,
  644. ))
  645. }
  646. }
  647. impl<T: Read> TryCompose<T, Decompressor<T>> for BrotliParams {
  648. type Error = Error;
  649. fn try_compose(self, inner: T) -> Result<Decompressor<T>> {
  650. Ok(Decompressor::new(inner, self.buf_sz))
  651. }
  652. }
  653. /// An envelopment of a key, which is tagged with the principal who the key is meant for.
  654. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)]
  655. pub struct Readcap {
  656. /// The principal this `Readcap` was issued to.
  657. issued_to: Principal,
  658. /// An encipherment of a block key using the public key of the principal.
  659. key: Ciphertext<SymKey>,
  660. }
  661. impl Readcap {
  662. pub fn new(issued_to: VarHash, key: Ciphertext<SymKey>) -> Readcap {
  663. Readcap {
  664. issued_to: Principal(issued_to),
  665. key,
  666. }
  667. }
  668. }
  669. #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
  670. pub struct WritecapBody {
  671. /// The principal this `Writecap` was issued to.
  672. issued_to: Principal,
  673. /// The path where this write caps's validity begins.
  674. path: BlockPath,
  675. /// The point in time after which this write cap is no longer valid.
  676. expires: Epoch,
  677. /// The public key used to sign this write cap.
  678. signing_key: AsymKeyPub<Sign>,
  679. }
  680. /// Verifies that a principal is authorized to write blocks in a tree.
  681. #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
  682. pub struct Writecap {
  683. /// A container for the fields of this writecap which are covered by the signature.
  684. body: WritecapBody,
  685. /// A digital signature which covers all of the fields in the write cap except for next.
  686. signature: Signature,
  687. /// The next write cap in the chain leading back to the root.
  688. next: Option<Box<Writecap>>,
  689. }
  690. /// Fragments are created from blocks using Erasure Encoding and stored with other nodes in the
  691. /// network to provide availability and redundancy of data.
  692. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
  693. pub struct Fragment {
  694. /// The path to the block this fragment is from.
  695. path: BlockPath,
  696. /// The serial number of this fragment.
  697. serial: FragmentSerial,
  698. /// The actual data.
  699. body: Vec<u8>,
  700. }
  701. impl Fragment {
  702. /// Create a new fragment with the given fields. If `path_str` cannot be parsed then a failed
  703. /// `Result` is returned containing a `PathError`.
  704. pub fn new(
  705. path_str: &str,
  706. serial_num: u32,
  707. body: Vec<u8>,
  708. ) -> std::result::Result<Fragment, BlockPathError> {
  709. let result = BlockPath::try_from(path_str);
  710. Ok(Fragment {
  711. path: result?,
  712. serial: FragmentSerial(serial_num),
  713. body,
  714. })
  715. }
  716. }
  717. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
  718. /// Structure for keeping track of block information in a directory.
  719. pub struct BlockRecord {
  720. /// The ID of the block. Note that this is only guaranteed to be unique in the directory this
  721. /// record is stored in.
  722. pub inode: u64,
  723. /// A mapping from fragment serial numbers to fragment records.
  724. /// TODO: Does this need to have a consistent order?
  725. pub frags: HashMap<FragmentSerial, FragmentRecord>,
  726. }
  727. #[derive(Debug, PartialEq, Serialize, Deserialize)]
  728. /// Structure for keeping track of server information in a directory.
  729. pub struct ServerRecord {
  730. /// The most up-to-date address for this server.
  731. addr: SocketAddr,
  732. /// The public credentials for this server.
  733. pub_creds: PublicCreds,
  734. }
  735. #[derive(Debug, PartialEq, Serialize, Deserialize)]
  736. pub enum DirEntry {
  737. Directory(BlockRecord),
  738. File(BlockRecord),
  739. Server(ServerRecord),
  740. }
  741. /// This is the body contained in directory blocks.
  742. #[derive(Debug, PartialEq, Serialize, Deserialize)]
  743. pub struct Directory {
  744. /// This block's descendants.
  745. entries: BTreeMap<String, DirEntry>,
  746. }
  747. impl Directory {
  748. pub fn new() -> Directory {
  749. Directory {
  750. entries: BTreeMap::new(),
  751. }
  752. }
  753. pub fn add_file(&mut self, name: String, inode: u64) -> Result<&mut BlockRecord> {
  754. let entry = match self.entries.entry(name) {
  755. btree_map::Entry::Occupied(entry) => {
  756. return Err(Error::custom(format!(
  757. "directory already contains entry '{}'",
  758. entry.key()
  759. )));
  760. }
  761. btree_map::Entry::Vacant(entry) => entry,
  762. };
  763. let dir_entry = entry.insert(DirEntry::File(BlockRecord {
  764. inode,
  765. frags: HashMap::new(),
  766. }));
  767. match dir_entry {
  768. DirEntry::File(record) => Ok(record),
  769. _ => Err(Error::custom("DirEntry was not the File variant")),
  770. }
  771. }
  772. }
  773. impl Default for Directory {
  774. fn default() -> Self {
  775. Self::new()
  776. }
  777. }
  778. /// Keeps track of which principal is storing a fragment.
  779. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
  780. pub struct FragmentRecord {
  781. /// The fragment serial number this record is for.
  782. serial: FragmentSerial,
  783. /// The principal who is storing this fragment.
  784. stored_by: Principal,
  785. }
  786. impl FragmentRecord {
  787. /// Creates a new `FragmentRecord` whose `serial` and `stored_by` fields are set to
  788. /// the given values.
  789. pub fn new(serial: u32, stored_by: VarHash) -> FragmentRecord {
  790. FragmentRecord {
  791. serial: FragmentSerial(serial),
  792. stored_by: Principal(stored_by),
  793. }
  794. }
  795. }
  796. /// An identifier for a security principal, which is any entity that can be authenticated.
  797. #[derive(
  798. Debug, PartialEq, Eq, Serialize, Deserialize, Hashable, Clone, Default, PartialOrd, Ord,
  799. )]
  800. pub struct Principal(VarHash);
  801. impl Principal {
  802. fn kind(&self) -> HashKind {
  803. HashKind::from(&self.0)
  804. }
  805. }
  806. impl Display for Principal {
  807. fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  808. self.0.fmt(f)
  809. }
  810. }
  811. /// Trait for types which are owned by a `Principal`.
  812. pub trait Principaled {
  813. /// Returns the `Principal` that owns `self`, using the given hash algorithm.
  814. fn principal_of_kind(&self, kind: HashKind) -> Principal;
  815. /// Returns the `Principal` that owns `self`, using the default hash algorithm.
  816. fn principal(&self) -> Principal {
  817. self.principal_of_kind(HashKind::default())
  818. }
  819. }
  820. /// An instant in time represented by the number of seconds since January 1st 1970, 00:00:00 UTC.
  821. #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
  822. pub struct Epoch(u64);
  823. impl Epoch {
  824. /// Returns the current epoch time.
  825. pub fn now() -> Epoch {
  826. let now = SystemTime::now();
  827. // If the system clock is before the unix epoch, just panic.
  828. let epoch = now.duration_since(SystemTime::UNIX_EPOCH).unwrap();
  829. Epoch(epoch.as_secs())
  830. }
  831. pub fn from_value(value: u64) -> Self {
  832. value.into()
  833. }
  834. pub fn value(self) -> u64 {
  835. self.into()
  836. }
  837. }
  838. impl Copy for Epoch {}
  839. impl From<u64> for Epoch {
  840. fn from(value: u64) -> Self {
  841. Self(value)
  842. }
  843. }
  844. impl From<Epoch> for u64 {
  845. fn from(value: Epoch) -> Self {
  846. value.0
  847. }
  848. }
  849. impl Add<Duration> for Epoch {
  850. type Output = Self;
  851. fn add(self, other: Duration) -> Self {
  852. Epoch(self.0 + other.as_secs())
  853. }
  854. }
  855. impl Sub<Duration> for Epoch {
  856. type Output = Self;
  857. fn sub(self, other: Duration) -> Self {
  858. Epoch(self.0 - other.as_secs())
  859. }
  860. }
  861. /// The serial number of a block fragment.
  862. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hashable)]
  863. pub struct FragmentSerial(u32);
  864. /// A struct which may contain a closure. When this struct is dropped, if it contains a closure
  865. /// then that closure is called. This closure can be removed by calling `disarm`.
  866. pub struct DropTrigger<F: FnOnce()>(Option<F>);
  867. impl<F: FnOnce()> DropTrigger<F> {
  868. pub fn new(trigger: F) -> DropTrigger<F> {
  869. DropTrigger(Some(trigger))
  870. }
  871. pub fn disarm(&mut self) {
  872. self.0.take();
  873. }
  874. }
  875. impl<F: FnOnce()> Drop for DropTrigger<F> {
  876. fn drop(&mut self) {
  877. if let Some(trigger) = self.0.take() {
  878. trigger()
  879. }
  880. }
  881. }
  882. #[cfg(feature = "testing")]
  883. #[cfg(test)]
  884. mod tests {
  885. use std::{fs::OpenOptions, io::Cursor, path::PathBuf};
  886. use crate::crypto::{
  887. tpm::{TpmCredStore, TpmCreds},
  888. ConcreteCreds, CredStore, CredsPriv,
  889. };
  890. use super::*;
  891. use btserde::{from_vec, to_vec};
  892. use tempdir::TempDir;
  893. use test_helpers::*;
  894. #[test]
  895. fn brotli_compress_decompress() {
  896. const SECT_SZ: usize = SECTOR_SZ_DEFAULT;
  897. const SECT_CT: usize = 16;
  898. let params = BrotliParams::new(SECT_SZ, 8, 20);
  899. let mut memory = Cursor::new([0u8; SECT_SZ * SECT_CT]);
  900. {
  901. let write: CompressorWriter<_> = params
  902. .clone()
  903. .try_compose(&mut memory)
  904. .expect("compose for write failed");
  905. write_fill(write, SECT_SZ, SECT_CT);
  906. }
  907. memory.seek(SeekFrom::Start(0)).expect("seek failed");
  908. {
  909. let read: Decompressor<_> = params
  910. .try_compose(&mut memory)
  911. .expect("compose for read failed");
  912. read_check(read, SECT_SZ, SECT_CT);
  913. }
  914. }
  915. #[test]
  916. fn block_can_create_empty() {
  917. let harness = SwtpmHarness::new().expect("failed to start swtpm");
  918. let context = harness.context().expect("failed to retrieve context");
  919. let cred_store = TpmCredStore::new(context, harness.state_path())
  920. .expect("failed to create TpmCredStore");
  921. let creds = cred_store.node_creds().expect("failed to get node creds");
  922. BlockOpenOptions::new()
  923. .with_inner(BtCursor::new(Vec::<u8>::new()))
  924. .with_creds(creds)
  925. .with_encrypt(true)
  926. .open()
  927. .expect("failed to open block");
  928. }
  929. /// Tests that the `BlockMetaBody` struct has an updated secrets struct after it is modified
  930. /// in the `access_secrets` method.
  931. #[test]
  932. fn block_meta_body_secrets_updated_after_access() {
  933. const UID: u32 = 1000;
  934. let creds = test_helpers::NODE_CREDS.clone();
  935. let vec = {
  936. let mut body = BlockMetaBody::new(&creds).expect("failed to create meta body");
  937. body.access_secrets(|secrets| {
  938. secrets.uid = UID;
  939. Ok(())
  940. })
  941. .expect("access secrets failed");
  942. to_vec(&body).expect("to_vec failed")
  943. };
  944. let mut body = from_vec::<BlockMetaBody>(&vec).expect("from_vec failed");
  945. body.unlock_block_key(&creds)
  946. .expect("unlock_block_key failed");
  947. let actual_uid = body
  948. .access_secrets(|secrets| Ok(secrets.uid))
  949. .expect("access_secrets failed");
  950. assert_eq!(UID, actual_uid);
  951. }
  952. struct BlockTestCase {
  953. root_creds: TpmCreds,
  954. node_creds: TpmCreds,
  955. _swtpm: SwtpmHarness,
  956. temp_dir: TempDir,
  957. }
  958. impl BlockTestCase {
  959. const ROOT_PASSWORD: &'static str = "(1337Prestidigitation7331)";
  960. fn new() -> BlockTestCase {
  961. let temp_dir = TempDir::new("block_test").expect("failed to create temp dir");
  962. let swtpm = SwtpmHarness::new().expect("failed to start swtpm");
  963. let context = swtpm.context().expect("failed to retrieve context");
  964. let cred_store = TpmCredStore::new(context, swtpm.state_path())
  965. .expect("failed to create TpmCredStore");
  966. let root_creds = cred_store
  967. .gen_root_creds(Self::ROOT_PASSWORD)
  968. .expect("failed to get root creds");
  969. let mut node_creds = cred_store.node_creds().expect("failed to get node creds");
  970. let writecap = root_creds
  971. .issue_writecap(
  972. node_creds.principal(),
  973. vec!["nodes".to_string(), "phone".to_string()],
  974. Epoch::now() + Duration::from_secs(3600),
  975. )
  976. .expect("failed to issue writecap");
  977. node_creds.set_writecap(writecap);
  978. BlockTestCase {
  979. temp_dir,
  980. _swtpm: swtpm,
  981. node_creds,
  982. root_creds,
  983. }
  984. }
  985. fn fs_path(&self, path: &crate::BlockPath) -> PathBuf {
  986. let mut fs_path = self.temp_dir.path().to_owned();
  987. fs_path.extend(path.components());
  988. fs_path
  989. }
  990. fn open_new(&mut self, path: &crate::BlockPath) -> Box<dyn Block> {
  991. let file = OpenOptions::new()
  992. .create_new(true)
  993. .read(true)
  994. .write(true)
  995. .open(&self.fs_path(path))
  996. .expect("failed to open file");
  997. let mut block = BlockOpenOptions::new()
  998. .with_inner(file)
  999. .with_creds(self.node_creds.clone())
  1000. .with_encrypt(true)
  1001. .open()
  1002. .expect("failed to open block");
  1003. block
  1004. .mut_meta_body()
  1005. .set_path(self.node_creds.writecap().unwrap().body.path.clone());
  1006. block
  1007. }
  1008. fn open_existing(&mut self, path: &crate::BlockPath) -> Box<dyn Block> {
  1009. let file = OpenOptions::new()
  1010. .read(true)
  1011. .write(true)
  1012. .open(&self.fs_path(path))
  1013. .expect("failed to reopen file");
  1014. BlockOpenOptions::new()
  1015. .with_inner(file)
  1016. .with_creds(self.node_creds.clone())
  1017. .with_encrypt(true)
  1018. .open()
  1019. .expect("failed to reopen block")
  1020. }
  1021. }
  1022. #[test]
  1023. fn block_contents_persisted() {
  1024. const EXPECTED: &[u8] = b"Silly sordid sulking sultans.";
  1025. let mut case = BlockTestCase::new();
  1026. let path = BlockPath::new(case.root_creds.principal(), vec!["test.blk".to_string()]);
  1027. {
  1028. let mut block = case.open_new(&path);
  1029. block.write(EXPECTED).expect("failed to write");
  1030. block.flush().expect("flush failed");
  1031. }
  1032. let mut block = case.open_existing(&path);
  1033. let mut actual = [0u8; EXPECTED.len()];
  1034. block.read(&mut actual).expect("read failed");
  1035. assert_eq!(EXPECTED, actual);
  1036. }
  1037. #[test]
  1038. fn block_write_twice() {
  1039. const EXPECTED: &[u8] = b"Cool callous calamitous colonels.";
  1040. const MID: usize = EXPECTED.len() / 2;
  1041. let mut case = BlockTestCase::new();
  1042. let path = BlockPath::new(case.root_creds.principal(), vec!["test.blk".to_string()]);
  1043. {
  1044. let mut block = case.open_new(&path);
  1045. block.write(&EXPECTED[..MID]).expect("first write failed");
  1046. block.flush().expect("first flush failed");
  1047. }
  1048. {
  1049. let mut block = case.open_existing(&path);
  1050. block
  1051. .seek(SeekFrom::Start(MID.try_into().unwrap()))
  1052. .expect("seek failed");
  1053. block.write(&EXPECTED[MID..]).expect("second write failed");
  1054. block.flush().expect("second flush failed");
  1055. }
  1056. {
  1057. let mut block = case.open_existing(&path);
  1058. let mut actual = [0u8; EXPECTED.len()];
  1059. block.read(&mut actual).expect("read failed");
  1060. assert_eq!(EXPECTED, actual);
  1061. }
  1062. }
  1063. #[test]
  1064. fn block_write_with_different_creds() {
  1065. const EXPECTED: &[u8] = b"Cool callous calamitous colonels.";
  1066. const MID: usize = EXPECTED.len() / 2;
  1067. let mut case = BlockTestCase::new();
  1068. let path = BlockPath::new(case.root_creds.principal(), vec!["test.blk".to_string()]);
  1069. let app_creds = {
  1070. let mut app_creds = ConcreteCreds::generate().expect("failed to generate app creds");
  1071. let writecap = case
  1072. .root_creds
  1073. .issue_writecap(
  1074. app_creds.principal(),
  1075. path.components().map(|e| e.to_string()).collect(),
  1076. Epoch::now() + Duration::from_secs(60),
  1077. )
  1078. .expect("failed to issue writecap");
  1079. app_creds.set_writecap(writecap);
  1080. app_creds
  1081. };
  1082. {
  1083. let mut block = case.open_new(&path);
  1084. block
  1085. .mut_meta_body()
  1086. .add_readcap_for(app_creds.principal(), &app_creds)
  1087. .expect("failed to add readcap");
  1088. block.write(&EXPECTED[..MID]).expect("first write failed");
  1089. block.flush().expect("first flush failed");
  1090. }
  1091. {
  1092. let file = OpenOptions::new()
  1093. .read(true)
  1094. .write(true)
  1095. .open(case.fs_path(&path))
  1096. .expect("failed to reopen file");
  1097. let mut block = BlockOpenOptions::new()
  1098. .with_inner(file)
  1099. // Note that this write is performed using app_creds.
  1100. .with_creds(app_creds)
  1101. .with_encrypt(true)
  1102. .open()
  1103. .expect("failed to reopen block");
  1104. block
  1105. .seek(SeekFrom::Start(MID.try_into().unwrap()))
  1106. .expect("seek failed");
  1107. block.write(&EXPECTED[MID..]).expect("second write failed");
  1108. block.flush().expect("second flush failed");
  1109. }
  1110. {
  1111. let file = OpenOptions::new()
  1112. .read(true)
  1113. .write(true)
  1114. .open(case.fs_path(&path))
  1115. .expect("failed to reopen file");
  1116. let mut block = BlockOpenOptions::new()
  1117. .with_inner(file)
  1118. .with_creds(case.node_creds)
  1119. .with_encrypt(true)
  1120. .open()
  1121. .expect("failed to reopen block");
  1122. let mut actual = [0u8; EXPECTED.len()];
  1123. block.read(&mut actual).expect("read failed");
  1124. assert_eq!(EXPECTED, actual);
  1125. }
  1126. }
  1127. }