lib.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. use lox_library::{
  2. bridge_table::{from_scalar, BridgeLine, BridgeTable, EncryptedBucket, MAX_BRIDGES_PER_BUCKET},
  3. proto::*,
  4. scalar_u32, IssuerPubKey, OPENINV_LENGTH,
  5. };
  6. use lox_utils::{EncBridgeTable, Invite};
  7. use std::collections::HashMap;
  8. pub mod networking;
  9. use crate::networking::Networking;
  10. // Helper functions to get public keys from vector
  11. pub fn get_lox_pub(lox_auth_pubkeys: &Vec<IssuerPubKey>) -> &IssuerPubKey {
  12. &lox_auth_pubkeys[0]
  13. }
  14. pub fn get_migration_pub(lox_auth_pubkeys: &Vec<IssuerPubKey>) -> &IssuerPubKey {
  15. &lox_auth_pubkeys[1]
  16. }
  17. pub fn get_migrationkey_pub(lox_auth_pubkeys: &Vec<IssuerPubKey>) -> &IssuerPubKey {
  18. &lox_auth_pubkeys[2]
  19. }
  20. pub fn get_reachability_pub(lox_auth_pubkeys: &Vec<IssuerPubKey>) -> &IssuerPubKey {
  21. &lox_auth_pubkeys[3]
  22. }
  23. pub fn get_invitation_pub(lox_auth_pubkeys: &Vec<IssuerPubKey>) -> &IssuerPubKey {
  24. &lox_auth_pubkeys[4]
  25. }
  26. // Helper function to check if credential is eligible for
  27. // promotion from level 0 to 1
  28. pub async fn eligible_for_trust_promotion(
  29. net: &dyn Networking,
  30. cred: &lox_library::cred::Lox,
  31. ) -> bool {
  32. let level_since: u32 = match scalar_u32(&cred.level_since) {
  33. Some(v) => v,
  34. None => return false,
  35. };
  36. scalar_u32(&cred.trust_level).unwrap() == 0
  37. && level_since + trust_promotion::UNTRUSTED_INTERVAL <= get_today(net).await
  38. }
  39. // Helper function to check if credential is eligible for
  40. // level up from level 1+
  41. pub async fn eligible_for_level_up(net: &dyn Networking, cred: &lox_library::cred::Lox) -> bool {
  42. let level_since: u32 = match scalar_u32(&cred.level_since) {
  43. Some(v) => v,
  44. None => return false,
  45. };
  46. let trust_level: usize = scalar_u32(&cred.trust_level).unwrap().try_into().unwrap();
  47. trust_level > 0
  48. && level_since + lox_library::proto::level_up::LEVEL_INTERVAL[trust_level]
  49. <= get_today(net).await
  50. }
  51. // Get current date from Lox Auth
  52. pub async fn get_today(net: &dyn Networking) -> u32 {
  53. let resp = net.request("/today".to_string(), [].to_vec()).await;
  54. let today: u32 = serde_json::from_slice(&resp).unwrap();
  55. today
  56. }
  57. // Download Lox Auth pubkeys
  58. pub async fn get_lox_auth_keys(net: &dyn Networking) -> Vec<IssuerPubKey> {
  59. let resp = net.request("/pubkeys".to_string(), [].to_vec()).await;
  60. let lox_auth_pubkeys: Vec<IssuerPubKey> = serde_json::from_slice(&resp).unwrap();
  61. lox_auth_pubkeys
  62. }
  63. // Get encrypted bridge table
  64. pub async fn get_reachability_credential(net: &dyn Networking) -> HashMap<u32, EncryptedBucket> {
  65. let resp = net.request("/reachability".to_string(), [].to_vec()).await;
  66. let reachability_cred: EncBridgeTable = serde_json::from_slice(&resp).unwrap();
  67. reachability_cred.etable
  68. }
  69. // Get encrypted bridge table from BridgeDB and decrypt our entry
  70. pub async fn get_bucket(
  71. net: &dyn Networking,
  72. lox_cred: &lox_library::cred::Lox,
  73. ) -> [BridgeLine; MAX_BRIDGES_PER_BUCKET] {
  74. let encbuckets = get_reachability_credential(net).await;
  75. let (id, key) = from_scalar(lox_cred.bucket).unwrap();
  76. let encbucket = match encbuckets.get(&id) {
  77. Some(encbucket) => encbucket,
  78. None => panic!("Provided ID not found"),
  79. };
  80. BridgeTable::decrypt_bucket(id, &key, &encbucket).unwrap().0
  81. }
  82. // Get an open invitation
  83. pub async fn get_open_invitation(net: &dyn Networking) -> [u8; OPENINV_LENGTH] {
  84. let resp = net.request("/invite".to_string(), [].to_vec()).await;
  85. let open_invite: [u8; OPENINV_LENGTH] = serde_json::from_slice::<Invite>(&resp).unwrap().invite;
  86. open_invite
  87. }
  88. // Get a Lox Credential from an open invitation
  89. pub async fn get_lox_credential(
  90. net: &dyn Networking,
  91. open_invite: &[u8; OPENINV_LENGTH],
  92. lox_pub: &IssuerPubKey,
  93. ) -> (lox_library::cred::Lox, BridgeLine) {
  94. let (req, state) = open_invite::request(&open_invite);
  95. let encoded_req: Vec<u8> = serde_json::to_vec(&req).unwrap();
  96. let encoded_resp = net.request("/openreq".to_string(), encoded_req).await;
  97. let decoded_resp: open_invite::Response = serde_json::from_slice(&encoded_resp).unwrap();
  98. let (cred, bridgeline) = open_invite::handle_response(state, decoded_resp, &lox_pub).unwrap();
  99. (cred, bridgeline)
  100. }
  101. // Get a migration credential to migrate to higher trust
  102. pub async fn trust_promotion(
  103. net: &dyn Networking,
  104. lox_cred: &lox_library::cred::Lox,
  105. lox_pub: &IssuerPubKey,
  106. ) -> lox_library::cred::Migration {
  107. let (req, state) = trust_promotion::request(&lox_cred, &lox_pub, get_today(net).await).unwrap();
  108. let encoded_req: Vec<u8> = serde_json::to_vec(&req).unwrap();
  109. let encoded_resp = net.request("/trustpromo".to_string(), encoded_req).await;
  110. let decoded_resp: trust_promotion::Response = serde_json::from_slice(&encoded_resp).unwrap();
  111. let migration_cred = trust_promotion::handle_response(state, decoded_resp).unwrap();
  112. migration_cred
  113. }
  114. // Promote from untrusted (trust level 0) to trusted (trust level 1)
  115. pub async fn trust_migration(
  116. net: &dyn Networking,
  117. lox_cred: &lox_library::cred::Lox,
  118. migration_cred: &lox_library::cred::Migration,
  119. lox_pub: &IssuerPubKey,
  120. migration_pub: &IssuerPubKey,
  121. ) -> lox_library::cred::Lox {
  122. let (req, state) =
  123. migration::request(lox_cred, migration_cred, lox_pub, migration_pub).unwrap();
  124. let encoded_req: Vec<u8> = serde_json::to_vec(&req).unwrap();
  125. let encoded_resp = net.request("/trustmig".to_string(), encoded_req).await;
  126. let decoded_resp: migration::Response = serde_json::from_slice(&encoded_resp).unwrap();
  127. let cred = migration::handle_response(state, decoded_resp, lox_pub).unwrap();
  128. cred
  129. }
  130. // Increase trust from at least level 1 to higher levels
  131. pub async fn level_up(
  132. net: &dyn Networking,
  133. lox_cred: &lox_library::cred::Lox,
  134. encbuckets: &HashMap<u32, EncryptedBucket>,
  135. lox_pub: &IssuerPubKey,
  136. reachability_pub: &IssuerPubKey,
  137. ) -> (lox_library::cred::Lox, [BridgeLine; MAX_BRIDGES_PER_BUCKET]) {
  138. // Read the bucket in the credential to get today's Bucket
  139. // Reachability credential
  140. let (id, key) = from_scalar(lox_cred.bucket).unwrap();
  141. let bucket = BridgeTable::decrypt_bucket(id, &key, &encbuckets.get(&id).unwrap()).unwrap();
  142. let reachcred = bucket.1.unwrap();
  143. // Use the Bucket Reachability credential to advance to the next
  144. // level
  145. let (req, state) = level_up::request(
  146. lox_cred,
  147. &reachcred,
  148. lox_pub,
  149. reachability_pub,
  150. get_today(net).await,
  151. )
  152. .unwrap();
  153. let encoded_req: Vec<u8> = serde_json::to_vec(&req).unwrap();
  154. let encoded_resp = net.request("/levelup".to_string(), encoded_req).await;
  155. let decoded_resp: level_up::Response = serde_json::from_slice(&encoded_resp).unwrap();
  156. let cred = level_up::handle_response(state, decoded_resp, lox_pub).unwrap();
  157. // Get bucket
  158. let (id, key) = from_scalar(lox_cred.bucket).unwrap();
  159. let bucket = BridgeTable::decrypt_bucket(id, &key, &encbuckets.get(&id).unwrap()).unwrap();
  160. (cred, bucket.0)
  161. }
  162. // Request an Invitation credential to give to a friend
  163. pub async fn issue_invite(
  164. net: &dyn Networking,
  165. lox_cred: &lox_library::cred::Lox,
  166. encbuckets: &HashMap<u32, EncryptedBucket>,
  167. lox_pub: &IssuerPubKey,
  168. reachability_pub: &IssuerPubKey,
  169. invitation_pub: &IssuerPubKey,
  170. ) -> (lox_library::cred::Lox, lox_library::cred::Invitation) {
  171. // Read the bucket in the credential to get today's Bucket
  172. // Reachability credential
  173. let (id, key) = from_scalar(lox_cred.bucket).unwrap();
  174. let bucket = BridgeTable::decrypt_bucket(id, &key, &encbuckets.get(&id).unwrap()).unwrap();
  175. let reachcred = bucket.1.unwrap();
  176. let (req, state) = issue_invite::request(
  177. lox_cred,
  178. &reachcred,
  179. lox_pub,
  180. reachability_pub,
  181. get_today(net).await,
  182. )
  183. .unwrap();
  184. let encoded_req: Vec<u8> = serde_json::to_vec(&req).unwrap();
  185. let encoded_resp = net.request("/issueinvite".to_string(), encoded_req).await;
  186. let decoded_resp: issue_invite::Response = serde_json::from_slice(&encoded_resp).unwrap();
  187. let (cred, invite) =
  188. issue_invite::handle_response(state, decoded_resp, lox_pub, invitation_pub).unwrap();
  189. (cred, invite)
  190. }
  191. // Redeem an Invitation credential to start at trust level 1
  192. pub async fn redeem_invite(
  193. net: &dyn Networking,
  194. invite: &lox_library::cred::Invitation,
  195. lox_pub: &IssuerPubKey,
  196. invitation_pub: &IssuerPubKey,
  197. ) -> (lox_library::cred::Lox, [BridgeLine; MAX_BRIDGES_PER_BUCKET]) {
  198. let (req, state) =
  199. redeem_invite::request(invite, invitation_pub, get_today(net).await).unwrap();
  200. let encoded_req: Vec<u8> = serde_json::to_vec(&req).unwrap();
  201. let encoded_resp = net.request("/redeem".to_string(), encoded_req).await;
  202. let decoded_resp: redeem_invite::Response = serde_json::from_slice(&encoded_resp).unwrap();
  203. let cred = redeem_invite::handle_response(state, decoded_resp, lox_pub).unwrap();
  204. let bucket = get_bucket(net, &cred).await;
  205. (cred, bucket)
  206. }
  207. // Check for a migration credential to move to a new bucket
  208. pub async fn check_blockage(
  209. net: &dyn Networking,
  210. lox_cred: &lox_library::cred::Lox,
  211. lox_pub: &IssuerPubKey,
  212. ) -> lox_library::cred::Migration {
  213. let (req, state) = check_blockage::request(lox_cred, lox_pub).unwrap();
  214. let encoded_req: Vec<u8> = serde_json::to_vec(&req).unwrap();
  215. let encoded_resp = net.request("/checkblockage".to_string(), encoded_req).await;
  216. let decoded_resp: check_blockage::Response = serde_json::from_slice(&encoded_resp).unwrap();
  217. let migcred = check_blockage::handle_response(state, decoded_resp).unwrap();
  218. migcred
  219. }
  220. // Migrate to a new bucket (must be level >= 3)
  221. pub async fn blockage_migration(
  222. net: &dyn Networking,
  223. lox_cred: &lox_library::cred::Lox,
  224. migcred: &lox_library::cred::Migration,
  225. lox_pub: &IssuerPubKey,
  226. migration_pub: &IssuerPubKey,
  227. ) -> lox_library::cred::Lox {
  228. let (req, state) =
  229. blockage_migration::request(lox_cred, migcred, lox_pub, migration_pub).unwrap();
  230. let encoded_req: Vec<u8> = serde_json::to_vec(&req).unwrap();
  231. let encoded_resp = net
  232. .request("/blockagemigration".to_string(), encoded_req)
  233. .await;
  234. let decoded_resp: blockage_migration::Response = serde_json::from_slice(&encoded_resp).unwrap();
  235. let cred = blockage_migration::handle_response(state, decoded_resp, lox_pub).unwrap();
  236. cred
  237. }
  238. #[cfg(test)]
  239. mod tests;