Commit 1658131
committed
fix: pre-initialize mTLS flag from cert SAN/CN to handle TLS session resumption in Wear OS onboarding
When setting up a Wear OS device the mTLS certificate-selection screen
was silently skipped if TLS session resumption occurred, causing the
watch to register without a client certificate and the server to return
HTTP 400.
Root cause: isTLSClientAuthNeeded in TLSWebViewClient is only set inside
onReceivedClientCertRequest. When the onboarding WebView reuses the main
app's existing TLS session (abbreviated handshake), the server never
issues a new CertificateRequest so the callback never fires — even with
ssl_session_tickets disabled on the server, because Android's Chromium
network stack maintains its own in-process TLS session cache.
Fix: add TLSWebViewClient.preInitializeTLSClientAuthState(targetHost)
which inspects the in-memory certificate chain (if any) and checks
whether it covers targetHost by matching the server hostname against
the certificate's Subject Alternative Names (SANs) — both DNS names
with wildcard support (RFC 2818 §3.1) and IP addresses — falling back
to the Common Name (CN) for legacy certificates without SANs.
Matching against the certificate rather than mere private-key presence
eliminates the false positive raised in review: a user with multiple
servers where only Server A requires mTLS will no longer see the cert-
selection screen when onboarding a watch for Server B, because the
loaded certificate will not match Server B's hostname.
ConnectionViewModel.init extracts the hostname from rawUrl and passes
it to preInitializeTLSClientAuthState() before emitting the auth URL
so the navigation layer sees the correct value.
Also updates ConnectionViewModelTest: the two existing private-key-
presence tests are replaced with five cert-host matching tests covering
exact DNS SANs, wildcard DNS SANs, a cert for a different host, no
certificate chain present, and CN-only fallback.
Made-with: Cursor0 parents commit 1658131
1,867 files changed
Lines changed: 182648 additions & 0 deletions
File tree
- .github
- ISSUE_TEMPLATE
- actions
- create-release-notes
- create-release-number
- download-translations
- inflate-secrets
- setup-build-env
- upload-sarif-results
- upload-test-results
- scripts
- workflows
- matchers
- .idea
- codeStyles
- inspectionProfiles
- runConfigurations
- .junie
- app
- src
- androidTest/kotlin/io/homeassistant/companion/android
- assist/wakeword
- launch
- debug
- kotlin/io/homeassistant/companion/android
- developer
- catalog
- res
- drawable
- mipmap-anydpi-v26
- mipmap-hdpi
- mipmap-mdpi
- mipmap-xhdpi
- mipmap-xxhdpi
- mipmap-xxxhdpi
- values
- xml
- full
- kotlin/io/homeassistant/companion/android
- assist/wakeword
- data/wear
- location
- matter
- views
- notifications
- onboarding
- sensors
- settings/wear
- views
- thread
- res
- raw
- values
- main
- assets
- wakeword
- kotlin/io/homeassistant/companion/android
- assist
- service
- ui
- wakeword
- authenticator
- barcode
- view
- controls
- frontend
- error
- externalbus
- incoming
- outgoing
- handler
- permissions
- session
- url
- improv
- ui
- launch
- link
- loading
- matter
- nfc
- views
- notifications
- onboarding
- connection
- localfirst
- locationforsecureconnection
- locationsharing
- manualserver
- nameyourdevice
- serverdiscovery
- sethomenetwork
- wearmtls
- welcome
- qs
- sensors
- settings
- assist
- controls
- views
- developer
- location
- views
- gestures
- views
- language
- license
- log
- notification
- views
- qs
- views
- sensor
- views
- server
- shortcuts
- views
- ssid
- views
- url
- views
- vehicle
- views
- views
- websocket
- views
- widgets
- views
- themes
- thread
- util
- compose
- entity
- media/player
- webview
- icondialog
- vehicle
- vehicle
- websocket
- webview
- addto
- externalbus
- insecure
- widgets
- assist
- button
- camera
- common
- entity
- mediaplayer
- template
- todo
- res
- drawable-night
- drawable-nodpi
- drawable-v24
- drawable-v26
- drawable-v31
- drawable
- layout-v31
- layout
- mipmap-anydpi-v26
- mipmap-hdpi
- mipmap-mdpi
- mipmap-xhdpi
- mipmap-xxhdpi
- mipmap-xxxhdpi
- values-night
- values-v27
- values-v31
- values
- xml
- minimal/kotlin/io/homeassistant/companion/android
- assist/wakeword
- location
- matter
- onboarding
- sensors
- settings/wear
- views
- thread
- screenshotTestFullDebug/reference/io/homeassistant/companion/android
- developer/HAComposeCatalogScreenshotTest
- frontend
- FrontendScreenScreenshotTest
- error/FrontendConnectionErrorScreenshotTest
- launch/link/LinkActivityScreenshotTest
- loading/LoadingScreenshotTest
- onboarding
- connection/ConnectionScreenshotTest
- localfirst/LocalFirstScreenshotTest
- locationforsecureconnection/LocationForSecureConnectionScreenshotTest
- locationsharing/LocationSharingScreenshotTest
- manualserver/ManualServerScreenshotTest
- nameyourdevice/NameYourDeviceScreenshotTest
- serverdiscovery/ServerDiscoveryScreenshotTest
- sethomenetwork/SetHomeNetworkScreenshotTest
- wearmtls/WearMTLSScreenshotTest
- welcome/WelcomeScreenshotTest
- settings
- assist/AssistSettingsScreenScreenshotTest
- gestures/GesturesFragmentScreenshotTest
- views
- SettingsRowScreenshotTest
- SettingsSubheaderScreenshotTest
- wear/views/SettingsWearOnboardingViewPreviewsTest
- util/compose
- HAAppScreenshotTest
- entity/EntityPickerScreenshotTest
- media/player/HAMediaPlayerScreenshotTest
- webview
- WebViewContentScreenScreenshotTest
- insecure/BlockInsecureScreenshotTest
- screenshotTest
- java/android/os
- kotlin/io/homeassistant/companion/android
- developer
- frontend
- error
- launch/link
- loading
- onboarding
- connection
- localfirst
- locationforsecureconnection
- locationsharing
- manualserver
- nameyourdevice
- serverdiscovery
- sethomenetwork
- wearmtls
- welcome
- settings
- assist
- gestures
- views
- wear/views
- util/compose
- entity
- media/player
- webview
- insecure
- test
- kotlin/io/homeassistant/companion/android
- assist
- service
- wakeword
- data/wear
- frontend
- error
- externalbus
- incoming
- outgoing
- handler
- permissions
- session
- url
- launch
- link
- onboarding
- connection
- localfirst
- locationforsecureconnection
- locationsharing
- manualserver
- nameyourdevice
- serverdiscovery
- sethomenetwork
- wearmtls
- welcome
- sensors
- settings
- assist
- developer/location
- wear
- util
- compose
- entity
- websocket
- webview
- addto
- insecure
- widgets
- entity
- todo
- automotive
- src
- full
- main
- build-logic
- convention
- src/main/kotlin
- io/homeassistant/companion/android
- common
- schemas/io.homeassistant.companion.android.database.AppDatabase
- src
- androidTest/kotlin/io/homeassistant/companion/android/database/migration
- debug/kotlin/io/homeassistant/companion/android/common/util
- main
- kotlin/io/homeassistant/companion/android
- common
- assist
- bluetooth
- ble
- compose
- composable
- theme
- data
- authentication
- impl
- entities
- connectivity
- integration
- impl
- entities
- keychain
- network
- prefs
- impl/entities
- servers
- websocket
- impl
- entities
- notifications
- sensors
- util
- di
- tts
- database
- authentication
- location
- migration
- notification
- qs
- sensor
- server
- settings
- wear
- widget
- converters
- di
- qualifiers
- util
- res
- drawable
- values-night-v31
- values-night
- values-v31
- values
- xml
- release/kotlin/io/homeassistant/companion/android/common/util
- screenshotTestDebug/reference/io/homeassistant/companion/android/compose/composable
- HABannerScreenshotTest
- HAButtonScreenshotTest
- HADetailsScreenshotTest
- HADropdownMenuScreenshotTest
- HAHorizontalDividerScreenshotTest
- HALabelScreenshottest
- HAModalScreenshotTest
- HAProgressScreenshotTest
- HARadioGroupScreenshotTest
- HASettingsCardScreenshotTest
- HASwitchScreenshotTest
- HATextFieldScreenshotTest
- screenshotTest/kotlin/io/homeassistant/companion/android/compose/composable
- test
- java/android/os
- kotlin/io/homeassistant/companion/android
- common
- assist
- data
- authentication
- connectivity
- integration
- impl
- entities
- network
- prefs
- servers
- websocket/impl
- entities
- sensors
- util
- database
- server
- widget
- sensors
- util
- fastlane
- metadata/android/en-US
- changelogs
- images
- phoneScreenshots
- sevenInchScreenshots
- tenInchScreenshots
- tvScreenshots
- wearScreenshots
- gradle
- wrapper
- lint
- src
- main/kotlin/io/homeassistant/lint
- annotation
- room
- serialization
- utils
- test/kotlin/io/homeassistant/lint
- annotation
- room
- serialization
- microfrontend
- src
- androidTest/kotlin/io/homeassistant/companion/android/microfrontend
- main
- cpp
- kotlin/io/homeassistant/companion/android/microfrontend
- testing-unit
- src/main/kotlin/io/homeassistant/companion/android
- fakes
- testing/unit
- wear
- src
- androidTest/kotlin/io/homeassistant/companion/android/splash
- debug/res
- drawable
- mipmap-anydpi
- main
- kotlin/io/homeassistant/companion/android
- complications
- views
- conversation
- views
- data
- home
- views
- notifications
- onboarding
- integration
- manual
- phoneinstall
- phone
- sensors
- splash
- theme
- tiles
- util
- viewHolders
- views
- res
- drawable-round
- drawable
- layout
- mipmap-anydpi
- raw
- values
- xml
- screenshotTestDebug/reference/io/homeassistant/companion/android/EntityListViewPreviewsTest
- screenshotTest
- java/android/os
- kotlin/io/homeassistant/companion/android
- test
- kotlin/io/homeassistant/companion/android
- data
- fakes
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
0 commit comments