diff --git a/homekit-controller/src/lib.rs b/homekit-controller/src/lib.rs index 976aa36..5a2badd 100644 --- a/homekit-controller/src/lib.rs +++ b/homekit-controller/src/lib.rs @@ -1,10 +1,12 @@ -use chacha20poly1305::{aead::generic_array::GenericArray, AeadInPlace, ChaCha20Poly1305, KeyInit}; +use chacha20poly1305::{ + aead::generic_array::GenericArray, AeadInPlace, ChaCha20Poly1305, KeyInit, Nonce, +}; use ed25519_dalek::{Signer, Verifier}; use hkdf::Hkdf; use sha2::Sha512; use std::{collections::HashMap, path::PathBuf}; use thiserror::Error; -use tlv8::{HomekitState, TlvEncode, TlvType}; +use tlv8::{HomekitState, TlvEncode, TlvError, TlvType}; use x25519_dalek::{EphemeralSecret, PublicKey}; use pairing_data::DevicePairingData; @@ -164,13 +166,9 @@ impl DevicePairingData { .encode(); // 10. Encrypt sub-TLV: encryptedData, authTag = ChaCha20-Poly1305(SessionKey, Nonce=”PV-Msg03”, AAD=, Msg=) - let nonce: [u8; 12] = [0; 4] - .iter() - .chain(b"PV-Msg03") - .copied() - .collect::>() - .try_into()?; - chacha.encrypt_in_place(GenericArray::from_slice(&nonce), &[], &mut encrypted_tlv)?; + let mut nonce = [0; 12]; + nonce[4..].copy_from_slice(b"PV-Msg03"); + chacha.encrypt_in_place(Nonce::from_slice(&nonce), &[], &mut encrypted_tlv)?; // 11/12 Construct TLV response and send to accessory let step3_response = decode( @@ -196,6 +194,14 @@ impl DevicePairingData { return Err(HomekitError::StateMismatch); } + if let Some(error) = step3_response.get(&TlvType::Error.into()) { + if let Some(e) = error.first().and_then(|v| TlvError::try_from(*v).ok()) { + return Err(e.into()); + } + log::error!("got tlv error from device but couldn't parse it from the data!"); + return Err(HomekitError::TlvNotFound); + } + // 5.7.4 M4: Accessory -> iOS Device – ‘Verify Finish Responseʼ // When the accessory receives , it must perform the following steps: // @@ -299,6 +305,14 @@ pub enum HomekitError { SomethingElse(String), #[error("addr parse")] AddrParse(#[from] std::net::AddrParseError), + #[error("tlv error from device")] + TlvDeviceError(TlvError), +} + +impl From for HomekitError { + fn from(value: TlvError) -> Self { + Self::TlvDeviceError(value) + } } impl From for HomekitError { diff --git a/homekit-controller/src/tlv8/mod.rs b/homekit-controller/src/tlv8/mod.rs index bc04c69..76cfff4 100644 --- a/homekit-controller/src/tlv8/mod.rs +++ b/homekit-controller/src/tlv8/mod.rs @@ -1,8 +1,7 @@ -use self::data_types::TlvError; use std::collections::HashMap; use thiserror::Error; -pub use data_types::{HomekitState, TlvType}; +pub use data_types::{HomekitState, TlvError, TlvType}; mod data_types;