Skip to content

Commit

Permalink
WIP: not working, will be force-pushed
Browse files Browse the repository at this point in the history
Signed-off-by: Martichou <[email protected]>
  • Loading branch information
Martichou committed Feb 14, 2024
1 parent c1b9edc commit 0109a1d
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 31 deletions.
29 changes: 29 additions & 0 deletions src/current_error.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
02-14 01:51:19.690 28945 28256 I NearbyConnections: (REDACTED) EndpointManager failed the next %s read/write for endpoint %s over its %s EndpointChannel.
02-14 01:51:19.690 28945 28256 I NearbyConnections: java.io.IOException: Failed to decode message on channel ENCRYPTED_WIFI_LAN for endpoint �
v)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at bqit.y(:com.google.android.gms@[email protected] (190408-604559810):245)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at bqit.x(:com.google.android.gms@[email protected] (190408-604559810):12)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at bqkf.b(:com.google.android.gms@[email protected] (190408-604559810):18)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at bqkb.run(:com.google.android.gms@[email protected] (190408-604559810):108)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at bqkf.run(:com.google.android.gms@[email protected] (190408-604559810):9)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at akvu.c(:com.google.android.gms@[email protected] (190408-604559810):50)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at akvu.run(:com.google.android.gms@[email protected] (190408-604559810):76)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at albi.run(:com.google.android.gms@[email protected] (190408-604559810):8)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at java.lang.Thread.run(Thread.java:1012)
02-14 01:51:19.690 28945 28256 I NearbyConnections: Caused by: java.security.SignatureException: javax.crypto.IllegalBlockSizeException: error:1e00007b:Cipher functions:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH
02-14 01:51:19.690 28945 28256 I NearbyConnections: at fbaf.c(:com.google.android.gms@[email protected] (190408-604559810):294)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at fbaf.b(:com.google.android.gms@[email protected] (190408-604559810):7)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at fayj.b(:com.google.android.gms@[email protected] (190408-604559810):24)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at fayg.j(:com.google.android.gms@[email protected] (190408-604559810):5)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at bqit.y(:com.google.android.gms@[email protected] (190408-604559810):64)
02-14 01:51:19.690 28945 28256 I NearbyConnections: ... 10 more
02-14 01:51:19.690 28945 28256 I NearbyConnections: Caused by: javax.crypto.IllegalBlockSizeException: error:1e00007b:Cipher functions:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH
02-14 01:51:19.690 28945 28256 I NearbyConnections: at com.google.android.gms.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at com.google.android.gms.org.conscrypt.OpenSSLEvpCipher.doFinalInternal(:com.google.android.gms@[email protected] (190408-604559810):20)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at com.google.android.gms.org.conscrypt.OpenSSLCipher.engineDoFinal(:com.google.android.gms@[email protected] (190408-604559810):7)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at javax.crypto.Cipher.doFinal(Cipher.java:2056)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at fbac.g(:com.google.android.gms@[email protected] (190408-604559810):36)
02-14 01:51:19.690 28945 28256 I NearbyConnections: at fbaf.c(:com.google.android.gms@[email protected] (190408-604559810):53)
02-14 01:51:19.690 28945 28256 I NearbyConnections: ... 14 more
134 changes: 103 additions & 31 deletions src/inbound.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use aes::cipher::block_padding::Pkcs7;
use aes::cipher::{BlockEncryptMut, KeyIvInit};
use aes::cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit};
use anyhow::anyhow;
use hmac::{Hmac, Mac};
use p256::ecdh::diffie_hellman;
Expand All @@ -14,7 +14,7 @@ use tokio::net::TcpStream;
use crate::location_nearby_connections::payload_transfer_frame::{
payload_header, PacketType, PayloadChunk, PayloadHeader,
};
use crate::location_nearby_connections::{OfflineFrame, PayloadTransferFrame};
use crate::location_nearby_connections::{KeepAliveFrame, OfflineFrame, PayloadTransferFrame};
use crate::securegcm::ukey2_alert::AlertType;
use crate::securegcm::{
ukey2_message, DeviceToDeviceMessage, GcmMetadata, Type, Ukey2Alert, Ukey2ClientFinished,
Expand All @@ -32,6 +32,7 @@ use crate::utils::{
use crate::{location_nearby_connections, sharing_nearby};

type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;
type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;
type HmacSha256 = Hmac<Sha256>;

#[derive(Debug)]
Expand All @@ -47,6 +48,7 @@ impl InboundRequest {
state: InnerState {
server_seq: 1,
state: State::Initial,
encryption_done: true,
remote_device_info: None,
cipher_commitment: None,
private_key: None,
Expand Down Expand Up @@ -119,11 +121,14 @@ impl InboundRequest {

self.update_state(|e: &mut InnerState| {
e.state = State::SentConnectionResponse;
// Reset seq
e.server_seq = 1;
});
}
_ => {
debug!("Handling SecureMessage frame");
let _smsg = SecureMessage::decode(&*frame_data);
let smsg = SecureMessage::decode(&*frame_data)?;
self.decrypt_and_process_secure_message(&smsg).await?;
}
}

Expand Down Expand Up @@ -367,6 +372,61 @@ impl InboundRequest {
Ok(())
}

async fn decrypt_and_process_secure_message(
&mut self,
smsg: &SecureMessage,
) -> Result<(), anyhow::Error> {
let mut hmac = HmacSha256::new_from_slice(self.state.recv_hmac_key.as_ref().unwrap())?;
hmac.update(&smsg.header_and_body);
let result = hmac.finalize();

// TODO - 100% this can be optimized
if result.into_bytes().to_vec() != smsg.signature {
return Err(anyhow!("hmac!=signature"));
}

let header_and_body = HeaderAndBody::decode(&*smsg.header_and_body)?;

let mut data = header_and_body.body;
let key = self.state.decrypt_key.as_ref().unwrap();
let decryptor =
Aes256CbcDec::new(key.as_slice().into(), header_and_body.header.iv().into());
let decrypted = match decryptor.decrypt_padded_mut::<Pkcs7>(&mut data) {
Ok(o) => o,
Err(e) => {
error!("error: {:?}", e);
return Err(anyhow!("Error encrypting pkt: {}", e));
}
};
let d2d_msg = DeviceToDeviceMessage::decode(decrypted)?;

let seq = self.state.server_seq;
if d2d_msg.sequence_number() != seq {
return Err(anyhow!(
"Error d2d_msg.sequence_number invalid ({} vs {})",
d2d_msg.sequence_number(),
seq
));
}

let offline = location_nearby_connections::OfflineFrame::decode(d2d_msg.message())?;

match offline.v1.as_ref().unwrap().r#type() {
location_nearby_connections::v1_frame::FrameType::PayloadTransfer => {
trace!("Received FrameType::PayloadTransfer");
},
location_nearby_connections::v1_frame::FrameType::KeepAlive => {
trace!("Sending keepalive");
self.send_keepalive(true).await?;
}
_ => {
error!("Unhandled offline frame encrypted: {:?}", offline);
}
}

Ok(())
}

fn finalize_key_exchange(
&mut self,
raw_peer_key: GenericPublicKey,
Expand Down Expand Up @@ -427,6 +487,7 @@ impl InboundRequest {
e.encrypt_key = Some(server_key);
e.send_hmac_key = Some(server_hmac_key);
e.pin_code = Some(to_four_digit_string(&auth_string));
e.encryption_done = true;
});

info!("Pin code: {:?}", self.state.pin_code);
Expand Down Expand Up @@ -527,31 +588,28 @@ impl InboundRequest {
let msg_data_size = msg_data.len();
let iv = gen_random(16);

let data_len = msg_data_size + 4;
let mut encrypted_buf: Vec<u8> = unsafe {
let mut buf = Vec::with_capacity(data_len + 16);
#[allow(clippy::uninit_vec)]
buf.set_len(data_len + 16);
buf
};

let key = self.state.encrypt_key.as_ref().unwrap();
let encryptor = Aes256CbcEnc::new(key.as_slice().into(), iv.as_slice().into());
let encrypted =
match encryptor.encrypt_padded_mut::<Pkcs7>(&mut encrypted_buf[4..], msg_data_size) {
Ok(o) => o,
Err(e) => {
error!("error: {:?}", e);
return Err(anyhow!("Error encrypting pkt: {}", e));
}
};

let mut bytes = vec![];
bytes.extend_from_slice(&msg_data_size.to_be_bytes());
bytes.extend_from_slice(encrypted);
// TODO - Not working (I guess, see current_error.txt)
// let data_len = msg_data_size + 4;
// let mut encrypted_buf: Vec<u8> = unsafe {
// let mut buf = Vec::with_capacity(data_len + 16);
// #[allow(clippy::uninit_vec)]
// buf.set_len(data_len + 16);
// buf
// };

// let key = self.state.encrypt_key.as_ref().unwrap();
// let encryptor = Aes256CbcEnc::new(key.as_slice().into(), iv.as_slice().into());
// let encrypted =
// match encryptor.encrypt_padded_mut::<Pkcs7>(&mut encrypted_buf, msg_data_size) {
// Ok(o) => o,
// Err(e) => {
// error!("error: {:?}", e);
// return Err(anyhow!("Error encrypting pkt: {}", e));
// }
// };

let hb = HeaderAndBody {
body: bytes,
body: encrypted_buf,
header: Header {
encryption_scheme: EncScheme::Aes256Cbc.into(),
signature_scheme: SigScheme::HmacSha256.into(),
Expand All @@ -567,8 +625,7 @@ impl InboundRequest {
},
};

let mut hmac =
HmacSha256::new_from_slice(self.state.send_hmac_key.as_ref().unwrap()).unwrap();
let mut hmac = HmacSha256::new_from_slice(self.state.send_hmac_key.as_ref().unwrap())?;
hmac.update(&hb.encode_to_vec());
let result = hmac.finalize();

Expand All @@ -582,6 +639,23 @@ impl InboundRequest {
Ok(())
}

async fn send_keepalive(&mut self, ack: bool) -> Result<(), anyhow::Error> {
let ack_frame = location_nearby_connections::OfflineFrame {
version: Some(location_nearby_connections::offline_frame::Version::V1.into()),
v1: Some(location_nearby_connections::V1Frame {
r#type: Some(location_nearby_connections::v1_frame::FrameType::KeepAlive.into()),
keep_alive: Some(KeepAliveFrame { ack: Some(ack) }),
..Default::default()
}),
};

if self.state.encryption_done {
self.encrypt_and_send(&ack_frame).await
} else {
self.send_frame(ack_frame.encode_to_vec()).await
}
}

async fn send_frame(&mut self, data: Vec<u8>) -> Result<(), anyhow::Error> {
let length = data.len();

Expand All @@ -604,13 +678,11 @@ impl InboundRequest {
}

fn get_seq_inc(&mut self) -> i32 {
let seq = self.state.server_seq;

self.update_state(|e| {
e.server_seq += 1;
});

seq
self.state.server_seq
}

fn update_state<F>(&mut self, f: F)
Expand Down
1 change: 1 addition & 0 deletions src/states.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub enum State {
pub struct InnerState {
pub server_seq: i32,
pub state: State,
pub encryption_done: bool,
pub remote_device_info: Option<RemoteDeviceInfo>,
pub cipher_commitment: Option<CipherCommitment>,
pub private_key: Option<SecretKey>,
Expand Down

0 comments on commit 0109a1d

Please sign in to comment.