From ac8488200d4043495a4709f5daddae5900542251 Mon Sep 17 00:00:00 2001 From: Seb3thehacker Date: Thu, 15 Oct 2026 11:09:41 -0700 Subject: [PATCH] keep homemade head units without a certificate working, and read wheel buttons and the knob as main does --- .../java/app/seb3thehacker/gearslip/GearslipRunner.kt | 6 ++---- .../main/java/app/seb3thehacker/gearslip/PhoneTls.kt | 10 ++++++---- .../test/java/app/seb3thehacker/gearslip/CryptoTest.kt | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt index ecdedbd..20acd9f 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt @@ -888,9 +888,8 @@ class GearslipRunner( for (key in Wire.allBytes(Wire.fields(keyEvent), 1)) { val fields = Wire.fields(key) val keycode = Wire.varint(fields, 1)?.toInt() ?: continue - val down = (Wire.varint(fields, 2) ?: continue) != 0L - if (Wire.varint(fields, 3) == null) continue - val longPress = (Wire.varint(fields, 4) ?: 0L) != 0L + val down = Wire.varint(fields, 2) == 1L + val longPress = Wire.varint(fields, 4) == 1L log.i("<- key event: keycode=$keycode ${if (down) "down" else "up"}${if (longPress) " long" else ""}") if (!CarKeys.onKey(keycode, down, longPress) && down) log.i("unhandled keycode=$keycode") } @@ -906,7 +905,6 @@ class GearslipRunner( val keycode = Wire.varint(fields, 1)?.toInt() ?: continue // int32, so a turn the other way arrives as a 64-bit two's complement varint. val delta = Wire.varint(fields, 2)?.toInt() ?: continue - if (keycode != 65536 || delta == 0) continue log.i("<- relative event: keycode=$keycode delta=$delta") CarKeys.onRotate(delta) } diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/PhoneTls.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/PhoneTls.kt index 973c678..6977f4d 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/PhoneTls.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/PhoneTls.kt @@ -38,9 +38,11 @@ class PhoneTls(keyStore: KeyStore, password: CharArray) { engine = context.createSSLEngine().apply { useClientMode = false - // Android Auto's phone endpoint requires the head unit to present a certificate. - needClientAuth = true - enabledProtocols = arrayOf("TLSv1.2") + // want, not need: we ask the head unit for its certificate so the run also tells + // us what real units present, but we never make the session depend on getting one. + // Homemade head units may have none. + wantClientAuth = true + enabledProtocols = arrayOf("TLSv1.2") // aasdk pins TLS 1.2 } engine.beginHandshake() } @@ -172,7 +174,7 @@ class PhoneTls(keyStore: KeyStore, password: CharArray) { } } } catch (_: SSLPeerUnverifiedException) { - log.i("head unit peer certificate is unavailable") + log.i("head unit presented NO certificate (we asked but did not require one)") } } diff --git a/gearslip/src/test/java/app/seb3thehacker/gearslip/CryptoTest.kt b/gearslip/src/test/java/app/seb3thehacker/gearslip/CryptoTest.kt index b0e6b3a..c4077bc 100644 --- a/gearslip/src/test/java/app/seb3thehacker/gearslip/CryptoTest.kt +++ b/gearslip/src/test/java/app/seb3thehacker/gearslip/CryptoTest.kt @@ -44,11 +44,11 @@ class CryptoTest { } @Test - fun `TLS rejects a head unit that does not present a client certificate`() { + fun `TLS still connects a head unit that presents no certificate, as homemade ones may`() { val generated = SelfSignedCert.generate() val identity = CertProvider.Identity(generated.keyStore, generated.certificate, SelfSignedCert.PASSWORD, "test") - assertFalse(TlsSelfTest.run(identity, withClientCertificate = false)) + assertTrue(TlsSelfTest.run(identity, withClientCertificate = false)) } @Test