4.7 KiB
homecore-hap
homecore-hap is HOMECORE's bounded, fail-closed HAP IP accessory server
(ADR-125). It implements the HAP R2 cryptographic pairing and transport
boundary without relying on the broken hap 0.1 pre-release crate.
Security and protocol coverage
- Pair-Setup M1-M6 uses the RFC 5054 3072-bit group with SHA-512, the HAP compatibility proof construction, HKDF-SHA512, ChaCha20-Poly1305, and Ed25519 long-term keys.
- Pair-Verify M1-M4 uses ephemeral X25519, strict Ed25519 transcript verification, HKDF-SHA512, and authenticated encrypted sub-TLVs.
- After successful M4, all HTTP and
EVENT/1.0traffic uses HAP records: two-byte little-endian authenticated lengths, at most 1024 plaintext bytes, independent directional keys, and monotonic 64-bit nonces. Authentication, replay, truncation, and oversize failures close the connection without an oracle response. /accessories,/characteristics, and/pairingsare inaccessible until Pair-Verify succeeds on that TCP connection. Pairings add/remove/list is restricted to a currently persisted administrator.- Accessory identity, Ed25519 seed, SRP salt/verifier, and controller records
are stored in a versioned file using same-directory atomic replacement.
Created Unix directories use mode
0700, files use0600, and permissive, oversized, symlinked, legacy, or malformed stores fail closed. - The raw setup code is returned only during first provisioning. Only its SRP
verifier is persisted;
SetupCoderedactsDebugoutput and zeroizes on drop. - Removing the last administrator atomically clears every pairing. Live sessions observe pairing revisions and are revoked, while the removal response is delivered before the requesting session closes.
The server also bounds connections, headers, bodies, request time, shutdown,
TLV sizes, controller counts, setup attempts, and concurrent Pair-Setup.
mDNS advertises the persisted accessory identifier and updates sf after
pairing or unpairing.
Provisioning and server integration
use std::{net::IpAddr, sync::Arc};
use homecore_hap::{
start_server, HapBridge, HapServerConfig, HapServiceRecord,
MdnsSdAdvertiser, PairingStore,
};
# async fn run() -> Result<(), Box<dyn std::error::Error>> {
let provisioned = PairingStore::load_or_create(
"/var/lib/homecore-hap/security.json",
)?;
if let Some(setup_code) = provisioned.setup_code.as_ref() {
// Send this once to a trusted local display or provisioning boundary.
println!("HAP setup code: {}", setup_code.expose());
}
let pairings = Arc::new(provisioned.store);
let record = HapServiceRecord::bridge(
"HOMECORE Bridge",
51826,
pairings.accessory_id()?,
);
let bridge = HapBridge::new(record);
let advertiser = Arc::new(MdnsSdAdvertiser::new(
"homecore",
"192.168.1.50".parse::<IpAddr>()?,
)?);
let server = start_server(
HapServerConfig::default(),
bridge.clone(),
pairings,
advertiser,
).await?;
// Feed HOMECORE StateChanged events through bridge.update_accessory(...).
server.shutdown().await?;
# Ok(())
# }
The mDNS device ID must equal the persisted accessory ID; startup rejects a mismatch. Real mDNS also requires a LAN-routable advertised address and multicast access.
Validation and remaining interoperability limits
The deterministic suite covers the HAP SRP session-key vector, complete
Pair-Setup and Pair-Verify ceremonies, transcript tampering, wrong proofs,
malformed/replayed/oversized records, atomic restart, last-admin removal, and
a real TCP lifecycle from Pair-Verify through encrypted /accessories.
This is protocol-level HAP R2 coverage, not a claim of Apple certification:
- It has not yet been exercised against a current Apple Home controller or the current commercial MFi specification.
- Transient and split Pair-Setup flags are rejected as
Unavailable. - Writable characteristic service calls, timed writes, resource endpoints, and stable persisted AID/IID allocation are not implemented. The present characteristic surface is read and event subscription only.
- Operational hardening still depends on protecting the host and the
0600security file; no hardware-backed key store is integrated.
Build and test:
cargo test -p homecore-hap --no-default-features
cargo test -p homecore-hap --features hap-server
cargo clippy -p homecore-hap --all-targets --features hap-server -- -D warnings