medic / cht-android

A native Android container for Community Health Toolkit (CHT) applications
GNU Affero General Public License v3.0
25 stars 49 forks source link

Blank white screen fails to load for domains where SSL certificate chain is invalid (CertPathValidatorException) #357

Open kennsippell opened 4 months ago

kennsippell commented 4 months ago

Describe the bug

To Reproduce Steps to reproduce the behavior:

  1. Open eCHIS Kenya 2.0
  2. Navigate to Kericho instance

Expected behavior Kericho is working in my browser on the phone, but doesn't load through the app All other eCHIS domains appear to be working as expected Kericho was working fine until they updated their TSL cert

Logs

2024-04-25 12:29:12.832  1743-4234  ActivityTaskManager     system_server                        I  START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.StartupActivity bnds=[288,313][540,678]} with LAUNCH_MULTIPLE from uid 10216 (BAL_ALLOW_ALLOWLISTED_COMPONENT) result code=2
2024-04-25 12:29:12.833  2475-2513  WindowManagerShell      com.android.systemui                 V  Transition requested (#2644): android.os.BinderProxy@73e5747 TransitionRequestInfo { type = OPEN, triggerTask = TaskInfo{userId=0 taskId=3918 displayId=0 isRunning=true baseIntent=Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.StartupActivity } baseActivity=ComponentInfo{org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.EmbeddedBrowserActivity} topActivity=ComponentInfo{org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.EmbeddedBrowserActivity} origActivity=null realActivity=ComponentInfo{org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.StartupActivity} numActivities=1 lastActiveTime=781963482 supportsMultiWindow=true resizeMode=1 isResizeable=true minWidth=-1 minHeight=-1 defaultMinSize=220 token=WCT{android.window.IWindowContainerToken$Stub$Proxy@c0cfb74} topActivityType=1 pictureInPictureParams=null shouldDockBigOverlays=false launchIntoPipHostTaskId=-1 lastParentTaskIdBeforePip=-1 displayCutoutSafeInsets=Rect(0, 132 - 0, 0) topActivityInfo=ActivityInfo{5dc989d org.medicmobile.webapp.mobile.EmbeddedBrowserActivity} launchCookies=[android.os.BinderProxy@bdb0112] positionInParent=Point(0, 0) parentTaskId=-1 isFocused=false isVisible=false isVisibleRequested=false isSleeping=false locusId=null displayAreaFeatureId=1 isTopActivityTransparent=false appCompatTaskInfo=AppCompatTaskInfo { topActivityInSizeCompat=false topActivityEligibleForLetterboxEducation= false isLetterboxDoubleTapEnabled= false topActivityEligibleForUserAspectRatioButton= false topActivityBoundsLetterboxed= false isFromLetterboxDoubleTap= false topActivityLetterboxVerticalPosition= -1 topActivityLetterboxHorizontalPosition= -1 topActivityLetterboxWidth=-1 topActivityLetterboxHeight=-1 isUserFullscreenOverrideEnabled=false cameraCompatControlState=hidden}}, pipTask = null, remoteTransition = RemoteTransition { remoteTransition = android.window.IRemoteTransition$Stub$Proxy@c7f20e3, appThread = android.app.IApplicationThread$Stub$Proxy@b85ae0, debugName = QuickstepLaunch }, displayChange = null, flags = 0, debugId = 2644 }
2024-04-25 12:29:12.833  2475-2513  WindowManagerShell      com.android.systemui                 D  onActivityRestartAttempt: ComponentInfo{org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.EmbeddedBrowserActivity}
2024-04-25 12:29:12.835  1743-2007  ActivityManager         system_server                        D  sync unfroze 21933 org.medicmobile.webapp.mobile.moh_kenya_echis for 1
2024-04-25 12:29:12.845  1743-2003  WindowManager           system_server                        V  Sent Transition (#2644) createdAt=04-25 12:29:12.826 via request=TransitionRequestInfo { type = OPEN, triggerTask = TaskInfo{userId=0 taskId=3918 displayId=0 isRunning=true baseIntent=Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.StartupActivity } baseActivity=ComponentInfo{org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.EmbeddedBrowserActivity} topActivity=ComponentInfo{org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.EmbeddedBrowserActivity} origActivity=null realActivity=ComponentInfo{org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.StartupActivity} numActivities=1 lastActiveTime=781963482 supportsMultiWindow=true resizeMode=1 isResizeable=true minWidth=-1 minHeight=-1 defaultMinSize=220 token=WCT{RemoteToken{4f5fa8d Task{d1055de #3918 type=standard A=10321:org.medicmobile.webapp.mobile.moh_kenya_echis}}} topActivityType=1 pictureInPictureParams=null shouldDockBigOverlays=false launchIntoPipHostTaskId=-1 lastParentTaskIdBeforePip=-1 displayCutoutSafeInsets=Rect(0, 132 - 0, 0) topActivityInfo=ActivityInfo{5ef2b5 org.medicmobile.webapp.mobile.EmbeddedBrowserActivity} launchCookies=[android.os.BinderProxy@c23a7ef] positionInParent=Point(0, 0) parentTaskId=-1 isFocused=false isVisible=false isVisibleRequested=false isSleeping=false locusId=null displayAreaFeatureId=1 isTopActivityTransparent=false appCompatTaskInfo=AppCompatTaskInfo { topActivityInSizeCompat=false topActivityEligibleForLetterboxEducation= false isLetterboxDoubleTapEnabled= false topActivityEligibleForUserAspectRatioButton= false topActivityBoundsLetterboxed= false isFromLetterboxDoubleTap= false topActivityLetterboxVerticalPosition= -1 topActivityLetterboxHorizontalPosition= -1 topActivityLetterboxWidth=-1 topActivityLetterboxHeight=-1 isUserFullscreenOverrideEnabled=false cameraCompatControlState=hidden}}, pipTask = null, remoteTransition = RemoteTransition { remoteTransition = android.window.IRemoteTransition$Stub$Proxy@4bfbd85, appThread = android.app.IApplicationThread$Stub$Proxy@b4067da, debugName = QuickstepLaunch }, displayChange = null, flags = 0, debugId = 2644 }
2024-04-25 12:29:12.845  1743-2003  WindowManager           system_server                        V      info={id=2644 t=OPEN f=0x0 trk=0 r=[0@Point(0, 0)] c=[
                                                                                                            {WCT{RemoteToken{4f5fa8d Task{d1055de #3918 type=standard A=10321:org.medicmobile.webapp.mobile.moh_kenya_echis}}} m=TO_FRONT f=MOVE_TO_TOP leash=Surface(name=Task=3918)/@0xb030bb7 sb=Rect(0, 0 - 1080, 2400) eb=Rect(0, 0 - 1080, 2400) d=0},
                                                                                                            {WCT{RemoteToken{bc373f3 Task{d5dc174 #1 type=home}}} m=TO_BACK f=SHOW_WALLPAPER leash=Surface(name=Task=1)/@0x900f05b sb=Rect(0, 0 - 1080, 2400) eb=Rect(0, 0 - 1080, 2400) d=0}
                                                                                                        ]}
2024-04-25 12:29:12.931  1743-3161  ImeTracker              system_server                        I  org.medicmobile.webapp.mobile.moh_kenya_echis:b9e067f0: onRequestHide at ORIGIN_SERVER_HIDE_INPUT reason HIDE_UNSPECIFIED_WINDOW
2024-04-25 12:29:12.931  1743-3161  ImeTracker              system_server                        I  org.medicmobile.webapp.mobile.moh_kenya_echis:b9e067f0: onCancelled at PHASE_SERVER_SHOULD_HIDE
2024-04-25 12:29:12.933  4734-4734  GoogleInpu...hodService com...gle.android.inputmethod.latin  I  GoogleInputMethodService.onStartInput():1950 onStartInput(EditorInfo{EditorInfo{packageName=org.medicmobile.webapp.mobile.moh_kenya_echis, inputType=0, inputTypeString=NULL, enableLearning=false, autoCorrection=false, autoComplete=false, imeOptions=0, privateImeOptions=null, actionName=UNSPECIFIED, actionLabel=null, initialSelStart=-1, initialSelEnd=-1, initialCapsMode=0, label=null, fieldId=0, fieldName=null, extras=null, hintText=null, hintLocales=[]}}, false)
2024-04-25 12:29:12.934  1743-2538  PackageConfigPersister  system_server                        W  App-specific configuration not found for packageName: org.medicmobile.webapp.mobile.moh_kenya_echis and userId: 0
2024-04-25 12:29:13.132 17524-17524 HotseatPre...Controller com...le.android.apps.nexuslauncher  D  Predicted items: [WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{org.medicmobile.webapp.mobile.moh_kenya_echis/org.medicmobile.webapp.mobile.StartupActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=eCHIS Kenya), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.android.vending/com.android.vending.AssetBrowserActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Play Store), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.google.android.apps.maps/com.google.android.maps.MapsActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Maps), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.chess/com.chess.splash.SplashActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Chess), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.instagram.android/com.instagram.android.activity.MainTabActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Instagram), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.google.android.calendar/com.android.calendar.AllInOneActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Calendar), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.microsoft.office.onenote/com.microsoft.office.onenote.ui.ONMSplashActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=OneNote), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.Slack/slack.features.home.HomeActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Slack), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.google.android.apps.translate/com.google.android.apps.translate.TranslateActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Translate), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.grabtaxi.passenger/com.grab.pax.newface.presentation.newface.NewFace} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Grab), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.google.android.deskclock/com.android.deskclock.DeskClock} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Clock), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.google.android.apps.authenticator2/com.google.android.apps.authenticator.AuthenticatorActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Authenticator), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.facebook.orca/com.facebook.orca.auth.StartScreenActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Messenger), WorkspaceItemInfo(id=-1 type=APP container=# com.android.launcher3.logger.LauncherAtom$ContainerInfo@19f79dd targetComponent=ComponentInfo{com.spotify.music/com.sp

Screenshots https://github.com/medic/cht-android/assets/9014751/7896ef70-4a6c-4d11-87a8-579e0c735146

Environment

Additional context Add any other context about the problem here. What have you tried? Is there a workaround?

garethbowen commented 4 months ago

Just to rule out the obvious, what webview version are you running?

When exactly was the certificate installed? I have seen it take days for the new cert to start being used and it could just be a matter of time.

Can you try with a device that doesn't have the app, or clear data for your app, or wipe the app on your device and reinstall, and see if that flushes the cache?

kennsippell commented 4 months ago

All other instances load fine through the Android app, so I doubt it is webview version. You can view the certificate at https://kericho.echis.go.ke/ I installed the app fresh to reproduce this. I have cleared data and can reproduce it again and again. The page loads fine on the same device in chrome.

garethbowen commented 4 months ago

All other instances load fine through the Android app, so I doubt it is webview version.

Right but the difference might be how the cert was generated so it is relevant.

The page loads fine on the same device in chrome.

Android manages Chrome and Webview separately so they are often on different versions.

kennsippell commented 4 months ago

@garethbowen Did you try this on your device with the steps provided and it isn't reproducing?

garethbowen commented 4 months ago

No unfortunately I don't have time to commit to this today, but just trying to help out with the few tips I have.

kennsippell commented 4 months ago

Webview is 123.0.06312.118 Chrome is 124.0.06367.82

Kericho has been inaccessible for 15 days. Can you help get this prioritized?

kennsippell commented 4 months ago

If we were seeing the old cert, I'd expect an expirty error but since I'm seeing this error about a trust anchor.

2024-04-25 13:55:40.452  7744-7827  cr_X509Util             org...webapp.mobile.moh_kenya_echis  I  Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
2024-04-25 13:55:40.463  7744-7837  chromium                org...webapp.mobile.moh_kenya_echis  E  [ERROR:ssl_client_socket_impl.cc(970)] handshake failed; returned -1, SSL error code 1, net_error -202
2024-04-25 13:55:40.487  1743-2410  ConnectivityService     system_server                        D  NetReassign [no changes] [c 2] [a 3] [i 8]
2024-04-25 13:55:40.536  7744-7837  chromium                org...webapp.mobile.moh_kenya_echis  E  [ERROR:ssl_client_socket_impl.cc(970)] handshake failed; returned -1, SSL error code 1, net_error -202

The certificate for Kericho is weak rated B here. I'll work to fix this certificate, but cht-android should not show a white screen after these CertPathValidatorException

mrjones-plip commented 4 months ago

I'm able to reproduced this error on kericho.echis.go.ke, just as Kenn's video shows. However, when I go to the Unbranded App (this APK), I and manually enter the URL, I actually get a different error:

click to see screenshot ![echis ke](https://github.com/medic/cht-android/assets/8253488/bacfb822-8738-468e-804f-025a8190d15b)

If possible, this ticket should make the Unable to contact server more accurate. I'd say both should say Error: xxx. This way the end user knows they can't proceed and we can add on Error: invalid TLS certificate along with existing errors.

Note that eventually kericho.echis.go.ke will be fixed and we won't be able to test with it. Bad SSL (badssl.com) is a GREAT resource for all your TLS testing needs. We can use incomplete-chain.badssl.com to test an incomplete chain when kericho gets fixed.