Check that we can use the credential to read a bucket
This commit is contained in:
parent
77b92036c7
commit
450c62bfc7
|
@ -17,6 +17,7 @@ hex_fmt = "0.3"
|
|||
aes-gcm = "0.8"
|
||||
base64 = "0.13"
|
||||
time = "0.2"
|
||||
subtle = "2.4"
|
||||
|
||||
[features]
|
||||
default = ["u64_backend"]
|
||||
|
|
|
@ -13,6 +13,7 @@ use aes_gcm::Aes128Gcm;
|
|||
use curve25519_dalek::scalar::Scalar;
|
||||
use rand::RngCore;
|
||||
use std::convert::TryInto;
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
/// Each bridge information line is serialized into this many bytes
|
||||
pub const BRIDGE_BYTES: usize = 220;
|
||||
|
@ -194,6 +195,16 @@ impl BridgeTable {
|
|||
plaintext.as_slice().try_into().unwrap(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Decrypt an individual encrypted bucket, given its id and key
|
||||
pub fn decrypt_bucket_id(
|
||||
&self,
|
||||
id: u32,
|
||||
key: &[u8; 16],
|
||||
) -> Result<[BridgeLine; MAX_BRIDGES_PER_BUCKET], aead::Error> {
|
||||
let encbucket = self.encbuckets[id as usize];
|
||||
BridgeTable::decrypt_bucket(key, &encbucket)
|
||||
}
|
||||
}
|
||||
|
||||
// Unit tests that require access to the testing-only function
|
||||
|
@ -225,18 +236,15 @@ mod tests {
|
|||
btable.encrypt_table();
|
||||
// Try to decrypt a 1-bridge bucket
|
||||
let key7 = btable.keys[7];
|
||||
let encbucket7 = btable.encbuckets[7];
|
||||
let bucket7 = BridgeTable::decrypt_bucket(&key7, &encbucket7)?;
|
||||
let bucket7 = btable.decrypt_bucket_id(7, &key7)?;
|
||||
println!("bucket 7 = {:?}", bucket7);
|
||||
// Try to decrypt a 3-bridge bucket
|
||||
let key24 = btable.keys[24];
|
||||
let encbucket24 = btable.encbuckets[24];
|
||||
let bucket24 = BridgeTable::decrypt_bucket(&key24, &encbucket24)?;
|
||||
let bucket24 = btable.decrypt_bucket_id(24, &key24)?;
|
||||
println!("bucket 24 = {:?}", bucket24);
|
||||
// Try to decrypt a bucket with the wrong key
|
||||
let key12 = btable.keys[12];
|
||||
let encbucket15 = btable.encbuckets[15];
|
||||
let res = BridgeTable::decrypt_bucket(&key12, &encbucket15).unwrap_err();
|
||||
let res = btable.decrypt_bucket_id(15, &key12).unwrap_err();
|
||||
println!("bucket key mismatch = {:?}", res);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -252,3 +260,16 @@ pub fn to_scalar(id: u32, key: [u8; 16]) -> Scalar {
|
|||
// This cannot fail, since we're only using the low 20 bytes of b
|
||||
Scalar::from_canonical_bytes(b).unwrap()
|
||||
}
|
||||
|
||||
/// Convert a Scalar attribute to an id and key if possible
|
||||
pub fn from_scalar(s: Scalar) -> Result<(u32, [u8; 16]), aead::Error> {
|
||||
// Check that the top 12 bytes of the Scalar are 0
|
||||
let sbytes = s.as_bytes();
|
||||
if sbytes[20..].ct_eq(&[0u8; 12]).unwrap_u8() == 0 {
|
||||
return Err(aead::Error);
|
||||
}
|
||||
let id = u32::from_le_bytes(sbytes[16..20].try_into().unwrap());
|
||||
let mut key: [u8; 16] = [0; 16];
|
||||
key.copy_from_slice(&sbytes[..16]);
|
||||
Ok((id, key))
|
||||
}
|
||||
|
|
|
@ -277,6 +277,11 @@ mod tests {
|
|||
let resp = ba.handle_open_invite(req).unwrap();
|
||||
let cred =
|
||||
open_invite::handle_response(state, resp, &ba.lox_pub, &ba.migration_pub).unwrap();
|
||||
|
||||
// Check that we can use the credential to read a bucket
|
||||
let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap();
|
||||
let bucket = ba.bridge_table.decrypt_bucket_id(id, &key).unwrap();
|
||||
println!("cred = {:?}", cred);
|
||||
println!("bucket = {:?}", bucket);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue