Compare commits

..

No commits in common. "cf31bad16822c2c044ba334d82d366318a0a8f08" and "e06917a5ac242a4a5c3e93bc44e92c99b8903217" have entirely different histories.

View File

@ -247,7 +247,6 @@ impl Into<JsValue> for ApiError {
#[wasm_bindgen] #[wasm_bindgen]
pub fn setup() { pub fn setup() {
wasm_logger::init(wasm_logger::Config::default()); wasm_logger::init(wasm_logger::Config::default());
log::debug!("Logging in wasm working");
} }
#[wasm_bindgen] #[wasm_bindgen]
@ -575,11 +574,13 @@ fn handle_transaction(
public_data: PublicKey, public_data: PublicKey,
) -> AnyhowResult<ApiReturn> { ) -> AnyhowResult<ApiReturn> {
let b_scan: SecretKey; let b_scan: SecretKey;
let local_member: Member;
let sp_wallet: SpClient; let sp_wallet: SpClient;
{ {
let local_device = lock_local_device()?; let local_device = lock_local_device()?;
sp_wallet = local_device.get_sp_client().clone(); sp_wallet = local_device.get_sp_client().clone();
b_scan = local_device.get_sp_client().get_scan_key(); b_scan = local_device.get_sp_client().get_scan_key();
local_member = local_device.to_member();
} }
// Basically a transaction that destroyed utxo is a transaction we sent. // Basically a transaction that destroyed utxo is a transaction we sent.
@ -609,7 +610,7 @@ fn handle_transaction(
let secret_hash = AnkMessageHash::from_message(shared_secret.as_byte_array()); let secret_hash = AnkMessageHash::from_message(shared_secret.as_byte_array());
// We still don't know who sent it, so we reply with a `Connect` prd // We still don't know who sent it, so we reply with a `Connect` prd
let prd_connect = Prd::new_connect(None, secret_hash, None); let prd_connect = Prd::new_connect(local_member, secret_hash, None);
let msg = prd_connect.to_network_msg(&sp_wallet)?; let msg = prd_connect.to_network_msg(&sp_wallet)?;
@ -691,7 +692,7 @@ fn confirm_prd(prd: &Prd, shared_secret: &AnkSharedSecretHash) -> AnyhowResult<S
let outpoint = prd.process_id; let outpoint = prd.process_id;
let local_device = lock_local_device()?; let local_device = lock_local_device()?;
let sender = local_device.get_pairing_commitment().ok_or(anyhow::Error::msg("Device not paired"))?; let sender = local_device.to_member();
let prd_confirm = Prd::new_confirm(outpoint, sender, prd.pcd_commitments.clone()); let prd_confirm = Prd::new_confirm(outpoint, sender, prd.pcd_commitments.clone());
@ -740,64 +741,54 @@ fn create_diffs(device: &MutexGuard<Device>, process: &Process, new_state: &Proc
Ok(diffs) Ok(diffs)
} }
fn handle_prd_connect(prd: Prd, secret: AnkSharedSecretHash, members_list: &OutPointMemberMap) -> AnyhowResult<ApiReturn> { fn handle_prd_connect(prd: Prd, secret: AnkSharedSecretHash) -> AnyhowResult<ApiReturn> {
let local_device = lock_local_device()?; let local_device = lock_local_device()?;
let local_address = local_device.get_address(); let local_member = local_device.to_member();
let sp_wallet = local_device.get_sp_client(); let sp_wallet = local_device.get_sp_client();
let secret_hash = AnkMessageHash::from_message(secret.as_byte_array()); let secret_hash = AnkMessageHash::from_message(secret.as_byte_array());
let mut shared_secrets = lock_shared_secrets()?; let mut shared_secrets = lock_shared_secrets()?;
if let Some(prev_proof) = prd.validation_tokens.get(0) { if let Some(prev_proof) = prd.validation_tokens.get(0) {
// We are receiving this as an answer to a prd connect we sent
if prd.proof.is_none() {
return Err(anyhow::Error::msg("Missing proof"));
}
// check that the proof is valid // check that the proof is valid
prev_proof.verify()?; prev_proof.verify()?;
// Check it's signed with our key // Check it's signed with our key
let local_address = SilentPaymentAddress::try_from(sp_wallet.get_receiving_address())?;
if prev_proof.get_key() != local_address.get_spend_key() { if prev_proof.get_key() != local_address.get_spend_key() {
return Err(anyhow::Error::msg("Previous proof of a prd connect isn't signed by us")); return Err(anyhow::Error::msg("Previous proof of a prd connect isn't signed by us"));
} }
// Check it signs a prd connect that contains the commitment to the shared secret // Check it signs a prd connect that contains the commitment to the shared secret
let empty_prd = Prd::new_connect(None, secret_hash, None); let empty_prd = Prd::new_connect(local_member, secret_hash, None);
let msg = AnkMessageHash::from_message(empty_prd.to_string().as_bytes()); let msg = AnkMessageHash::from_message(empty_prd.to_string().as_bytes());
if *msg.as_byte_array() != prev_proof.get_message() { if *msg.as_byte_array() != prev_proof.get_message() {
return Err(anyhow::Error::msg("Previous proof signs another message")); return Err(anyhow::Error::msg("Previous proof signs another message"));
} }
// Now we can confirm the secret and link it to an address
// If sender provided its pairing id we can confirm the secret and link it to an address let proof = prd.proof.unwrap();
if prd.sender.is_some() { let actual_sender = prd.sender.get_address_for_key(&proof.get_key())
let actual_sender = members_list.0.get(&prd.sender.unwrap()).ok_or(anyhow::Error::msg("Sender not found"))?.get_address_for_key(&prd.proof.unwrap().get_key()) .ok_or(anyhow::Error::msg("Signer of the proof is not part of sender"))?;
.ok_or(anyhow::Error::msg("Signer of the proof is not part of sender"))?; shared_secrets.confirm_secret_for_address(secret, actual_sender.clone().try_into()?);
shared_secrets.confirm_secret_for_address(secret, actual_sender.clone().try_into()?); let mut secrets_return = SecretsStore::new();
let mut secrets_return = SecretsStore::new(); secrets_return.confirm_secret_for_address(secret, actual_sender.try_into()?);
secrets_return.confirm_secret_for_address(secret, actual_sender.try_into()?); return Ok(ApiReturn {
return Ok(ApiReturn { secrets: Some(secrets_return),
secrets: Some(secrets_return), ..Default::default()
..Default::default() })
})
} else {
// otherwise we can't confirm the secret so we just do nothing
return Ok(ApiReturn::default());
}
} else { } else {
// We sent a transaction to some address and they answer with a prd connect let proof = prd.proof.unwrap();
if prd.proof.is_none() { let actual_sender = prd.sender.get_address_for_key(&proof.get_key())
return Err(anyhow::Error::msg("Missing proof")); .ok_or(anyhow::Error::msg("Signer of the proof is not part of sender"))?;
}
// TODO check that the key in the proof match what we have in the secret store shared_secrets.confirm_secret_for_address(secret, actual_sender.clone().try_into()?);
let sender = local_device.get_pairing_commitment(); let mut secrets_return = SecretsStore::new();
secrets_return.confirm_secret_for_address(secret, actual_sender.try_into()?);
// We create a prd connect with their own proof in validation tokens so that they can be sure who they're sharing the secret with let prd_connect = Prd::new_connect(local_member, secret_hash, prd.proof);
let prd_connect = Prd::new_connect(sender, secret_hash, prd.proof);
let msg = prd_connect.to_network_msg(sp_wallet)?; let msg = prd_connect.to_network_msg(sp_wallet)?;
let cipher = encrypt_with_key(secret.as_byte_array(), msg.as_bytes())?; let cipher = encrypt_with_key(secret.as_byte_array(), msg.as_bytes())?;
return Ok(ApiReturn { return Ok(ApiReturn {
ciphers_to_send: vec![cipher.to_lower_hex_string()], ciphers_to_send: vec![cipher.to_lower_hex_string()],
secrets: Some(secrets_return),
..Default::default() ..Default::default()
}) })
} }
@ -813,7 +804,7 @@ fn handle_prd(
// Connect is a bit different here because there's no associated process // Connect is a bit different here because there's no associated process
// Let's handle that case separately // Let's handle that case separately
if prd.prd_type == PrdType::Connect { if prd.prd_type == PrdType::Connect {
return handle_prd_connect(prd, secret, members_list); return handle_prd_connect(prd, secret);
} }
let outpoint = prd.process_id; let outpoint = prd.process_id;
@ -922,8 +913,15 @@ fn handle_prd(
PrdType::Request => { PrdType::Request => {
// We are being requested encrypted data for one or more states, to be uploaded on storage // We are being requested encrypted data for one or more states, to be uploaded on storage
let states: Vec<[u8; 32]> = serde_json::from_str(&prd.payload)?; let states: Vec<[u8; 32]> = serde_json::from_str(&prd.payload)?;
let requester = if let Some((requester_process_id, _)) = members_list.0.iter()
let requester = prd.sender.ok_or(anyhow::Error::msg("Missing sender"))?; .find(|(outpoint, member)| {
**member == prd.sender
})
{
requester_process_id
} else {
return Err(AnyhowError::msg("Unknown requester"));
};
// diffs will trigger upload of the encrypted data on storage // diffs will trigger upload of the encrypted data on storage
let mut diffs = vec![]; let mut diffs = vec![];
@ -959,7 +957,8 @@ fn handle_prd(
relevant_fields.extend(fields); relevant_fields.extend(fields);
} }
let sender = local_device.get_pairing_commitment().ok_or(AnyhowError::msg("Device not paired"))?; let sender: Member = local_device
.to_member();
let mut full_prd = Prd::new_update( let mut full_prd = Prd::new_update(
outpoint, outpoint,
@ -973,7 +972,7 @@ fn handle_prd(
full_prd.filter_keys(&relevant_fields); full_prd.filter_keys(&relevant_fields);
let prd_msg = full_prd.to_network_msg(sp_wallet)?; let prd_msg = full_prd.to_network_msg(sp_wallet)?;
let addresses = members_list.0.get(&sender).ok_or(AnyhowError::msg("Unknown requester"))?.get_addresses(); let addresses = prd.sender.get_addresses();
for sp_address in addresses.into_iter() { for sp_address in addresses.into_iter() {
// We skip our own device address, no point sending ourself a cipher // We skip our own device address, no point sending ourself a cipher
if sp_address == local_address { if sp_address == local_address {
@ -1031,7 +1030,7 @@ fn handle_decrypted_message(
processes: &OutPointProcessMap processes: &OutPointProcessMap
) -> anyhow::Result<ApiReturn> { ) -> anyhow::Result<ApiReturn> {
let local_address: SilentPaymentAddress = lock_local_device()?.get_address(); let local_address: SilentPaymentAddress = lock_local_device()?.get_address();
if let Ok(prd) = Prd::extract_from_message(&plain, local_address, members_list) { if let Ok(prd) = Prd::extract_from_message(&plain, local_address) {
handle_prd(prd, secret, members_list, processes) handle_prd(prd, secret, members_list, processes)
} else { } else {
Err(anyhow::Error::msg("Failed to handle decrypted message")) Err(anyhow::Error::msg("Failed to handle decrypted message"))
@ -1381,11 +1380,13 @@ pub fn request_data(process_id: String, state_ids_str: Vec<String>, roles: JsVal
return Err(ApiError::new("No valid state ids provided".to_owned())); return Err(ApiError::new("No valid state ids provided".to_owned()));
} }
// TODO actually sort members that have data in common with us (even in different roles)
let mut send_to: HashSet<SilentPaymentAddress> = HashSet::new(); let mut send_to: HashSet<SilentPaymentAddress> = HashSet::new();
for role in roles { for role in roles {
for (_, role_def) in role { for (_, role_def) in role {
let pairing_ids = &role_def.members; let pairing_ids = &role_def.members;
if !pairing_ids.contains(&sender_pairing_id) {
continue;
}
for pairing_id in pairing_ids { for pairing_id in pairing_ids {
if let Some(member) = members_list.0.get(pairing_id) { if let Some(member) = members_list.0.get(pairing_id) {
for address in member.get_addresses() { for address in member.get_addresses() {
@ -1399,7 +1400,7 @@ pub fn request_data(process_id: String, state_ids_str: Vec<String>, roles: JsVal
let prd_request = Prd::new_request( let prd_request = Prd::new_request(
process_id, process_id,
sender_pairing_id, members_list.0.get(&sender_pairing_id).unwrap().clone(),
state_ids state_ids
); );
@ -1469,7 +1470,8 @@ pub fn create_update_message(
} }
} }
let sender: OutPoint = local_device.get_pairing_commitment().ok_or(AnyhowError::msg("Device not paired"))?; let sender: Member = local_device
.to_member();
let full_prd = Prd::new_update( let full_prd = Prd::new_update(
process_id, process_id,
@ -1639,9 +1641,8 @@ fn new_response_prd(process_id: OutPoint, update_state: &ProcessState, members_l
let proof = update_state.validation_tokens.iter().find(|t| t.get_key() == our_key) let proof = update_state.validation_tokens.iter().find(|t| t.get_key() == our_key)
.ok_or(AnyhowError::msg("We haven't added our validation token yet".to_owned()))?; .ok_or(AnyhowError::msg("We haven't added our validation token yet".to_owned()))?;
let sender: OutPoint = local_device let sender: Member = local_device
.get_pairing_commitment() .to_member();
.ok_or(AnyhowError::msg("Device not paired"))?;
let response_prd = Prd::new_response( let response_prd = Prd::new_response(
process_id, process_id,