thunderbird / thunderbird/thunderbird-android

Unable to use client cert in store

Open
#5,642 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Kotlin
Stars
14k
Forks
2.8k
Avg merge
3d 3h
Merged PRs (30d)
57

Description

Forgive me if this is an android related issue as I uncovered it while I was migrating from a samsung galaxy s10 to a samsung galaxy s21. Also, sorry for the redacted info.

When trying to use a client cert I am not prompted to select one from the store. Instead I the field is auto-filled in with a random 192 bit string, which judging by the logs is a 'certificate alias'

image

Clicking on the menu generates a new random string/alias.

** steps **
I created a pkcs12 store without a password

~  openssl pkcs12 -export -inkey /path/to/client.key -in /path/to/client.crt -out mail.android.p12

And imported it without any apparent issue.
image

This shouldn't be a pki issue, these certs have been used for a while. neomutt is happily using them at the moment.


# Issuer hash matches hash of ca cert.
~  openssl x509 -noout -hash -fingerprint -in /path/to/ca.crt
80d4da41
SHA1 Fingerprint=A2:F3:94:39:92:D4:FE:FB:E1:BE:74:03:D3:27:E4:F6:2C:D8:12:A8

~  openssl x509 -noout -issuer_hash -in /path/to/client.crt
80d4da41

And the ca cert is on the device.

image

Logs

Here is a snippet from the logs, let me know if you'd like the whole thing. IT's about 2k lines.

09-03 14:34:20.898 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203581072]
09-03 14:34:20.908 29947 29947 I ViewRootImpl@1d0c9a8[AccountSetupIncoming]: MSG_WINDOW_FOCUS_CHANGED 1 1
09-03 14:34:20.908 29947 29947 D InputMethodManager: prepareNavigationBarInfo() DecorView@b4e2e1[AccountSetupIncoming]
09-03 14:34:20.908 29947 29947 D InputMethodManager: getNavigationBarColor() -855310
09-03 14:34:20.914 29947 29947 D InputMethodManager: prepareNavigationBarInfo() DecorView@b4e2e1[AccountSetupIncoming]
09-03 14:34:20.914 29947 29947 D InputMethodManager: getNavigationBarColor() -855310
09-03 14:34:20.914 29947 29947 V InputMethodManager: Starting input: tba=com.fsck.k9 ic=null mNaviBarColor -855310 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false
09-03 14:34:20.914 29947 29947 D InputMethodManager: startInputInner - Id : 0
09-03 14:34:20.914 29947 29947 I InputMethodManager: startInputInner - mService.startInputOrWindowGainedFocus
09-03 14:34:20.915 29947 29947 D InputTransport: Input channel constructed: 'ClientS', fd=98
09-03 14:34:20.915 29947 29947 D InputTransport: Input channel destroyed: 'ClientS', fd=96
09-03 14:34:20.923 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505203987280]
09-03 14:34:20.923 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203987280]
09-03 14:34:20.925 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505203672592]
09-03 14:34:20.925 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203672592]
09-03 14:34:20.925 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505203671712]
09-03 14:34:20.925 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203671712]
09-03 14:34:21.316 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505203676640]
09-03 14:34:21.316 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203676640]
09-03 14:34:21.316 29947 29947 I SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0x52d24dd / android.view.SurfaceControl.readFromParcel:1117 android.view.IWindowSession$Stub$Proxy.relayout:1810 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9971 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995
09-03 14:34:21.316 29947 29947 I SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0x8d55293 / android.view.SurfaceControl.readFromParcel:1117 android.view.IWindowSession$Stub$Proxy.relayout:1820 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9971 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995
09-03 14:34:21.319 29947 29947 I ViewRootImpl@1a92b82[AccountSettingsActivity]: Relayout returned: old=(0,0,1080,2400) new=(0,0,1080,2400) req=(1080,2400)8 dur=8 res=0x5 s={false 0} ch=true fn=239
09-03 14:34:21.320 29947 29947 I ViewRootImpl@1a92b82[AccountSettingsActivity]: stopped(true) old=false
09-03 14:34:21.333 29947 29947 I SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0x52d24dd / android.view.SurfaceControl.readFromParcel:1117 android.view.IWindowSession$Stub$Proxy.relayout:1810 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9971 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995
09-03 14:34:21.333 29947 29947 I SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0x8d55293 / android.view.SurfaceControl.readFromParcel:1117 android.view.IWindowSession$Stub$Proxy.relayout:1820 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9971 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995
09-03 14:34:21.333 29947 29947 I ViewRootImpl@1a92b82[AccountSettingsActivity]: Relayout returned: old=(0,0,1080,2400) new=(0,0,1080,2400) req=(1080,2400)8 dur=2 res=0x5 s={false 0} ch=false fn=-1
09-03 14:34:28.463 29947 29947 I ViewRootImpl@1d0c9a8[AccountSetupIncoming]: ViewPostIme pointer 0
09-03 14:34:28.512 29947 29947 I ViewRootImpl@1d0c9a8[AccountSetupIncoming]: ViewPostIme pointer 1
09-03 14:34:28.544 29947 29947 I ViewRootImpl@1d0c9a8[AccountSetupIncoming]: MSG_WINDOW_FOCUS_CHANGED 0 1
09-03 14:34:28.579 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505203676816]
09-03 14:34:28.579 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203676816]
09-03 14:34:28.580 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505203679984]
09-03 14:34:28.580 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203679984]
09-03 14:34:28.580 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505203681216]
09-03 14:34:28.580 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203681216]
09-03 14:34:28.618 29947 29947 D InputTransport: Input channel destroyed: 'ClientS', fd=98
09-03 14:34:28.620 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505203677168]
09-03 14:34:28.620 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203677168]
09-03 14:34:28.725 29947  2340 D ClientCertificateSpinner: User has selected client certificate alias: 1Ydi0FpNMN2J3ay1vp54WQ==   # <<<<---- HERE
09-03 14:34:28.735 29947 29947 I ViewRootImpl@1d0c9a8[AccountSetupIncoming]: stopped(false) old=false
09-03 14:34:28.747 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505203283456]
09-03 14:34:28.747 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203283456]
09-03 14:34:28.748 29947 29947 I SurfaceControl: assignNativeObject: nativeObject = 0 Surface(name=null)/@0x3133c97 / android.view.SurfaceControl.readFromParcel:1117 android.view.IWindowSession$Stub$Proxy.relayout:1820 android.view.ViewRootImpl.relayoutWindow:9005 android.view.ViewRootImpl.performTraversals:3360 android.view.ViewRootImpl.doTraversal:2618 android.view.ViewRootImpl$TraversalRunnable.run:9971 android.view.Choreographer$CallbackRecord.run:1010 android.view.Choreographer.doCallbacks:809 android.view.Choreographer.doFrame:744 android.view.Choreographer$FrameDisplayEventReceiver.run:995
09-03 14:34:28.748 29947 29947 I ViewRootImpl@1d0c9a8[AccountSetupIncoming]: Relayout returned: old=(0,0,1080,2400) new=(0,0,1080,2400) req=(1080,2400)0 dur=5 res=0x1 s={true 509498616640} ch=false fn=78
09-03 14:34:28.749 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505204079680]
09-03 14:34:28.749 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505204079680]
09-03 14:34:28.749 29947 29947 I SurfaceControl: nativeRelease nativeObject s[505203283456]
09-03 14:34:28.749 29947 29947 I SurfaceControl: nativeRelease nativeObject e[505203283456]
09-03 14:34:28.749 29947 29947 I ViewRootImpl@1d0c9a8[AccountSetupIncoming]: MSG_WINDOW_FOCUS_CHANGED 1 1
09-03 14:34:28.749 29947 29947 D InputMethodManager: prepareNavigationBarInfo() DecorView@b4e2e1[AccountSetupIncoming]
09-03 14:34:28.749 29947 29947 D InputMethodManager: getNavigationBarColor() -855310
09-03 14:34:28.752 29947 29947 D InputMethodManager: prepareNavigationBarInfo() DecorView@b4e2e1[AccountSetupIncoming]

and for posterity sake here is a slightly redacted version of the cert info so you can see the key usage and what not

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 122 (0x7a)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: redacted
        Validity
            Not Before: Apr 15 16:45:04 2020 GMT
            Not After : Apr 13 16:45:04 2030 GMT
        Subject: C = C , ST = ST, O = O, OU = OU, CN = emai@address.com, emailAddress = email@address.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:df:27:19:2f:26:6c:c4:f2:02:15:10:b4:1a:2b:
                    80:58:b3:ee:c9:f8:8a:53:e9:eb:b0:98:16:71:77:
                    6e:2f:bc:00:99:2f:f4:a1:7f:68:07:c8:83:c5:86:
                    fc:1d:f7:88:da:ef:f8:69:d5:17:ee:d0:ae:a2:4f:
                    07:dc:8e:9b:c2
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, E-mail Protection
            Netscape Cert Type:
                SSL Client, SSL Server, S/MIME
            X509v3 Subject Alternative Name:
                DNS:email@address.com
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                address.com
            X509v3 Subject Key Identifier:
                D3:56:2C:11:88:9B:BD:69:E5:DD:C3:30:9B:CB:0C:C0:8B:11:13:81
            X509v3 Authority Key Identifier:
                keyid:30:62:8E:50:61:6E:C3:8D:AB:8A:C3:75:1B:7E:6C:B3:55:7D:66:C2

    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:ec:6f:b7:ef:8c:22:81:60:c7:19:a4:c1:f4:
         d1:d1:af:4e:c9:4c:52:c0:44:2d:cb:e3:0f:ad:c6:07:56:e0:
         3c:02:20:01:41:bd:e3:f3:6c:27:bb:66:46:0c:5c:18:d7:87:
         72:c4:30:5a:e6:11:fc:d6:7d:07:6e:ac:c6:52:61:c9:fc

Thanks in advance and let me know if I could be of any more help.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the ClientCertificateSpinner log entry and the AccountSetupIncoming flow, then compare how the imported PKCS12 client certificate is presented and selected. Use the reported Android steps and logs to reproduce the random alias behavior; done means the client certificate can be selected from the device store instead of displaying a generated alias.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
mobile, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.