main.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. // The dead code warnings create too much noise during wire-framing.
  2. // TODO: Delete this prior to release.
  3. #![allow(dead_code)]
  4. use std::{
  5. collections::HashMap,
  6. convert::TryFrom,
  7. hash::Hash as Hashable,
  8. fmt::{self, Display, Formatter},
  9. };
  10. use serde::{Serialize, Deserialize};
  11. use serde_big_array::BigArray;
  12. #[cfg(test)]
  13. mod test_helpers;
  14. #[cfg(test)]
  15. mod serde_tests;
  16. mod crypto;
  17. use crypto::{Hash, Signature, Key, Cryptotext};
  18. /// A Block tagged with its version number.
  19. #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
  20. enum VersionedBlock {
  21. V0(Block)
  22. }
  23. /// A container which binds together ciphertext along with the metadata needed to identify,
  24. /// verify and decrypt it.
  25. #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
  26. struct Block {
  27. /// Identifies this block and defines its location in the tree.
  28. path: Path,
  29. /// This field contains a collection of `ReadCap`s indexed by the principal who holds them.
  30. /// `ReadCap`s are envelopments of the key used to encrypt this block.
  31. read_caps: HashMap<Principal, Cryptotext<Key>>,
  32. /// This field is used to verify that the signer of this block had permission to write it.
  33. /// It contains a certificate chain that must lead back to the root key for the tree this block
  34. /// is part of.
  35. write_cap: WriteCap,
  36. /// The encrypted data contained in this block.
  37. body: Cryptotext<Vec<u8>>,
  38. /// The contents of the block are covered by a digital signature contained in this field.
  39. signature: Signature
  40. }
  41. /// An envelopment of a key, which is tagged with the principal who the key is meant for.
  42. #[derive(Debug, PartialEq, Serialize, Deserialize)]
  43. struct ReadCap {
  44. /// The principal this `ReadCap` was issued to.
  45. issued_to: Principal,
  46. /// An encipherment of a block key using the public key of the principal.
  47. key: Cryptotext<Key>,
  48. }
  49. impl ReadCap {
  50. fn new(issued_to: Hash, key: Cryptotext<Key>) -> ReadCap {
  51. ReadCap { issued_to: Principal(issued_to), key }
  52. }
  53. }
  54. /// Verifies that a principal is authorized to write blocks in a tree.
  55. #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
  56. struct WriteCap {
  57. /// The principal this `WriteCap` was issued to.
  58. issued_to: Principal,
  59. /// The path where this write caps's validity begins.
  60. path: Path,
  61. /// The point in time after which this write cap is no longer valid.
  62. expires: Epoch,
  63. /// The public key used to sign this write cap.
  64. signing_key: Key,
  65. /// A digital signature which covers all of the fields in the write cap except for next.
  66. signature: Signature,
  67. /// The next write cap in the chain leading back to the root.
  68. next: Option<Box<WriteCap>>,
  69. }
  70. /// Fragments are created from blocks using Erasure Encoding and stored with other nodes in the
  71. /// network to provide availability and redundancy of data.
  72. #[derive(Debug, PartialEq, Serialize, Deserialize)]
  73. struct Fragment {
  74. /// The path to the block this fragment is from.
  75. path: Path,
  76. /// The serial number of this fragment.
  77. serial: FragmentSerial,
  78. /// The actual data.
  79. body: Vec<u8>,
  80. }
  81. impl Fragment {
  82. /// Create a new fragment with the given fields. If `path_str` cannot be parsed then a failed
  83. /// `Result` is returned containing a `PathError`.
  84. fn new(path_str: &str, serial_num: u32, body: Vec<u8>) -> Result<Fragment, PathError> {
  85. let result = Path::try_from(path_str);
  86. Ok(Fragment {
  87. path: result?,
  88. serial: FragmentSerial(serial_num),
  89. body
  90. })
  91. }
  92. }
  93. /// The body of every non-leaf node in a tree contains this data structure.
  94. #[derive(Debug, PartialEq, Serialize, Deserialize)]
  95. struct Directory {
  96. /// The nodes that are attached to the tree at this block.
  97. nodes: Vec<Principal>,
  98. /// This block's descendants.
  99. children: HashMap<String, HashMap<FragmentSerial, FragmentRecord>>,
  100. }
  101. /// Keeps track of which principal is storing a fragment.
  102. #[derive(Debug, PartialEq, Serialize, Deserialize)]
  103. struct FragmentRecord {
  104. /// The fragment serial number this record is for.
  105. serial: FragmentSerial,
  106. /// The principal who is storing this fragment.
  107. stored_by: Principal,
  108. }
  109. impl FragmentRecord {
  110. /// Creates a new `FragmentRecord` whose `serial` and `stored_by` fields are set to
  111. /// the given values.
  112. fn new(serial: u32, stored_by: Hash) -> FragmentRecord {
  113. FragmentRecord {
  114. serial: FragmentSerial(serial),
  115. stored_by: Principal(stored_by),
  116. }
  117. }
  118. }
  119. /// An identifier for a security principal, which is any entity that can be authenticated.
  120. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hashable, Clone)]
  121. struct Principal(Hash);
  122. /// An identifier for a block in a tree.
  123. #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
  124. struct Path {
  125. owner: Principal,
  126. components: Vec<String>,
  127. }
  128. impl Path {
  129. /// The character that is used to separate path components.
  130. const SEP: char = '/';
  131. /// The limit, in bytes, of a `Path`'s length.
  132. const BYTE_LIMIT: usize = 4096;
  133. /// Returns a result which, when successful, contains the index after the last character in the
  134. /// current path component.
  135. fn component_end<I: Iterator<Item = (usize, char)>>(
  136. start: usize, first: char, pairs: &mut I
  137. ) -> Result<usize, PathError> {
  138. if first == Path::SEP {
  139. return Err(PathError::EmptyComponent);
  140. }
  141. let end;
  142. let mut last = start;
  143. loop {
  144. match pairs.next() {
  145. Some((index, Path::SEP)) => {
  146. end = index;
  147. break;
  148. },
  149. Some((index, _)) => last = index,
  150. None => {
  151. end = last + 1;
  152. break
  153. }
  154. }
  155. }
  156. if end == start {
  157. Err(PathError::EmptyComponent)
  158. }
  159. else {
  160. Ok(end)
  161. }
  162. }
  163. /// Asserts that the number of bytes in the given string is no more than `Path::BYTE_LIMIT`.
  164. fn assert_not_too_long(string: &str) -> Result<(), PathError> {
  165. let len = string.len();
  166. if len > Path::BYTE_LIMIT {
  167. return Err(PathError::PathTooLong(len))
  168. }
  169. Ok(())
  170. }
  171. /// Returns true if `other` is a subpath of this `Path`.
  172. fn contains(&self, other: &Path) -> bool {
  173. if self.owner != other.owner {
  174. return false;
  175. };
  176. // This path must be no longer than the other path.
  177. if self.components.len() > other.components.len() {
  178. return false;
  179. }
  180. // Skip the component containing the owner.
  181. let self_iter = self.components.iter().skip(1);
  182. let other_iter = other.components.iter().skip(1);
  183. for pair in self_iter.zip(other_iter) {
  184. if pair.0 != pair.1 {
  185. return false;
  186. }
  187. }
  188. true
  189. }
  190. }
  191. impl<'s> TryFrom<&'s str> for Path {
  192. type Error = PathError;
  193. fn try_from(string: &'s str) -> Result<Path, PathError> {
  194. Path::assert_not_too_long(string)?;
  195. let mut pairs = string.char_indices();
  196. let mut components = Vec::new();
  197. let mut last_end = 0;
  198. while let Some((start, c)) = pairs.next() {
  199. let end = Path::component_end(start, c, &mut pairs)?;
  200. last_end = end;
  201. let slice = &string[start..end];
  202. components.push(slice.to_string());
  203. }
  204. // An empty component is added to the end to indicate if there was a trailing slash.
  205. if string.len() - 1 == last_end {
  206. components.push("".to_string());
  207. }
  208. let leading = components.get(0).ok_or(PathError::InvalidLeadingComponent)?;
  209. let hash = Hash::try_from(leading.as_str())
  210. .map_err(|_| PathError::InvalidLeadingComponent)?;
  211. Ok(Path {
  212. owner: Principal(hash),
  213. components,
  214. })
  215. }
  216. }
  217. impl Display for Path {
  218. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  219. if self.components.is_empty() {
  220. return write!(f, "");
  221. };
  222. let mut iter = self.components.iter();
  223. let first = iter.next().unwrap();
  224. let mut output = write!(f, "{}", first);
  225. for component in iter {
  226. output = write!(f, "{}{}", Path::SEP, component)
  227. }
  228. output
  229. }
  230. }
  231. /// Errors which can occur when converting a string to a `Path`.
  232. #[derive(Debug, PartialEq)]
  233. enum PathError {
  234. /// Occurs when the number of bytes in a string is greater than `Path::BYTE_LIMIT`.
  235. PathTooLong(usize),
  236. /// Indicates that a path string was empty.
  237. Empty,
  238. /// Occurs when a component in a path string was empty.
  239. EmptyComponent,
  240. /// Occurs when the leading component of a path is not in the correct format.
  241. InvalidLeadingComponent,
  242. }
  243. impl Display for PathError {
  244. fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
  245. match self {
  246. PathError::PathTooLong(length) => formatter.write_fmt(format_args!(
  247. "path contained {} bytes, which is over the {} byte limit",
  248. length,
  249. Path::BYTE_LIMIT)
  250. ),
  251. PathError::Empty => formatter.write_str("path was empty"),
  252. PathError::EmptyComponent => formatter.write_str("component of path was empty"),
  253. PathError::InvalidLeadingComponent
  254. => formatter.write_str("invalid leading path component")
  255. }
  256. }
  257. }
  258. /// An instant in time represented by the number of seconds since January 1st 1970, 00:00:00 UTC.
  259. #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
  260. struct Epoch(i64);
  261. /// The serial number of a block fragment.
  262. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hashable)]
  263. struct FragmentSerial(u32);
  264. fn main() {
  265. println!("Hello, world!");
  266. }
  267. #[cfg(test)]
  268. mod tests {
  269. use super::*;
  270. use test_helpers::*;
  271. fn path_from_str_test_case(
  272. expected: Result<Path, PathError>, input: &str
  273. ) -> Result<(), PathError> {
  274. let result = Path::try_from(input);
  275. assert_eq!(expected, result);
  276. Ok(())
  277. }
  278. #[test]
  279. fn path_from_str_multiple_components_ok() -> Result<(), PathError> {
  280. let expected = make_path(vec!["red", "green", "blue"]);
  281. let input = format!("{}/red/green/blue", expected.owner.0);
  282. path_from_str_test_case(Ok(expected), input.as_str())?;
  283. Ok(())
  284. }
  285. #[test]
  286. fn path_from_str_one_component_ok() -> Result<(), PathError> {
  287. let expected = make_path(vec![]);
  288. let input = expected.owner.0.to_string();
  289. path_from_str_test_case(Ok(expected), input.as_str())?;
  290. Ok(())
  291. }
  292. #[test]
  293. fn path_from_str_trailing_slash_ok() -> Result<(), PathError> {
  294. // Notice the empty component at the end of this path due to the trailing slash.
  295. let expected = make_path(vec!["orange", "banana", "shotgun", ""]);
  296. let input = format!("{}/orange/banana/shotgun/", expected.owner.0);
  297. path_from_str_test_case(Ok(expected), input.as_str())?;
  298. Ok(())
  299. }
  300. #[test]
  301. fn path_from_str_path_too_long_fail() -> Result<(), PathError> {
  302. let principal = make_principal();
  303. let input = format!("{}/{}", principal.0, "*".repeat(4097));
  304. let expected = Err(PathError::PathTooLong(input.len()));
  305. path_from_str_test_case(expected, input.as_str())?;
  306. Ok(())
  307. }
  308. #[test]
  309. fn path_from_str_multiple_slashes_fail() -> Result<(), PathError> {
  310. let expected = Err(PathError::EmptyComponent);
  311. let input = format!("{}//orange", make_principal().0);
  312. path_from_str_test_case(expected, input.as_str())?;
  313. Ok(())
  314. }
  315. #[test]
  316. fn path_from_str_leading_slash_fail() -> Result<(), PathError> {
  317. let expected = Err(PathError::EmptyComponent);
  318. let input = format!("/{}/orange/banana/shotgun", make_principal().0);
  319. path_from_str_test_case(expected, input.as_str())?;
  320. Ok(())
  321. }
  322. #[test]
  323. fn path_round_trip() -> Result<(), PathError> {
  324. let expected = make_path(vec!["interstitial", "inter-related", "intersections"]);
  325. let actual = Path::try_from(expected.to_string().as_str())?;
  326. assert_eq!(expected, actual);
  327. Ok(())
  328. }
  329. #[test]
  330. fn path_contains_true() {
  331. let larger = make_path(vec!["apps"]);
  332. let smaller = make_path(vec!["apps", "bohdi"]);
  333. assert!(larger.contains(&smaller));
  334. }
  335. #[test]
  336. fn path_contains_true_only_owner() {
  337. let larger = make_path(vec![]);
  338. let smaller = make_path(vec![]);
  339. assert!(larger.contains(&smaller));
  340. }
  341. #[test]
  342. fn path_contains_false_self_is_longer() {
  343. let first = make_path(vec!["apps", "bohdi"]);
  344. let second = make_path(vec!["apps"]);
  345. assert!(!first.contains(&second));
  346. }
  347. #[test]
  348. fn path_contains_false_same_owners() {
  349. let first = make_path(vec!["apps"]);
  350. let second = make_path(vec!["nodes"]);
  351. assert!(!first.contains(&second));
  352. }
  353. #[test]
  354. fn path_contains_false_different_owners() {
  355. let first = make_path(vec!["apps"]);
  356. let mut second = make_path(vec!["apps"]);
  357. second.owner = Principal(Hash::Sha2_256(PRINCIPAL2));
  358. assert!(!first.contains(&second));
  359. }
  360. }