3.1 KiB
3.1 KiB
PortalCam for macOS (mac2)
Native macOS companion app (PortalCam.app) and CoreMediaIO Camera Extension (CamExtension) for streaming high-definition video and audio from Portal TV.
Security Architecture
PortalCam uses a channel-bound, zero-knowledge authentication scheme to pair with Portal TV without sending secrets over the network or exposing connections to Man-in-the-Middle (MITM) proxies:
- Self-Signed ECDSA P-256 TLS:
- Portal TV serves all endpoints over HTTPS via an on-device generated ECDSA NIST P-256 (
secp256r1) certificate.
- Portal TV serves all endpoints over HTTPS via an on-device generated ECDSA NIST P-256 (
- Channel-Bound SRP-6a Handshake (RFC 5054):
- Initiation: User clicks Pair in the app. The app calls
POST https://<portal-ip>:5654/auth/srp/initover an ephemeral TLS session. - Channel Binding: The app extracts the presented leaf TLS certificate DER and computes:
\mathbf{tls\_hash} = \text{SHA256}(\text{cert\_der}) - Proof
M_1Generation: The user enters the 6-digit PIN displayed on the TV. The client computes:M_1 = \text{SHA256}(\text{pad256}(A) \parallel \text{pad256}(B) \parallel K \parallel s \parallel \mathbf{tls\_hash})and submits it toPOST https://<portal-ip>:5654/auth/srp/verify. - Mutual Proof
M_2Verification: The Portal TV verifiesM_1against its own certificate hash. If verified, it returns server proofM_2:M_2 = \text{SHA256}(\text{pad256}(A) \parallel M_1 \parallel K \parallel \mathbf{tls\_hash})along with a random 256-bit bearer token. - Client Verification: The app verifies
M_2to confirm the Portal independently knows the shared secret before trusting the server.
- Initiation: User clicks Pair in the app. The app calls
Why Active MITM Attacks Cannot Succeed
If an attacker deploys a rogue proxy:
- The rogue proxy presents a substitute TLS certificate
C_{\text{rogue}}to the Mac. - The Mac computes
M_1using\text{SHA256}(C_{\text{rogue}}). - The Portal verifies
M_1using\text{SHA256}(C_{\text{portal}}). - Because the certificate fingerprints differ,
M_1verification fails on the Portal TV. - The attacker cannot forge
M_1orM_2without knowing the ephemeral PIN, which is displayed solely on the physical TV screen and never leaves the room.
Certificate Pinning & Keychain Storage
Once pairing succeeds:
- The 256-bit bearer token and the certificate's SHA-256 fingerprint are saved in the macOS Data Protection Keychain under access group
ENT9X9U544.com.kovtash.portalcam:portalAuthToken— Bearer auth tokenportalPinnedCertSha256— Hex SHA-256 digest of the server's ECDSA certificate
- A fallback copy is mirrored into the shared App Group
UserDefaults(ENT9X9U544.com.kovtash.portalcam) for seamless access by the sandboxed camera extension. PortalPinnedSessionDelegateevaluates all subsequent HTTPS requests (/video.h264,/audio.aac,/control/*). Any TLS certificate mismatch aborts the connection immediately.
Building and Installing
cd mac2/PortalCam
xcodebuild -scheme PortalCam -configuration Debug build -derivedDataPath ./build
killall PortalCam 2>/dev/null || true
cp -R ./build/Build/Products/Debug/PortalCam.app /Applications/
open /Applications/PortalCam.app