Skip to content

X4 Pro (stock XT Licorice 260924): Unlocker fails at TLS handshake with BadCertificate (macOS) #44

Closed

Description

@idzeeboo-alt

Device: Xteink X4 Pro, stock firmware XT Licorice 260924 (Build: FW 1c34d6f-dirty, IDF v6.0.1). Xteink pushed this update to the device the morning I tried the Unlocker.
Tool: Xteink Unlocker 0.2.37 (app and helper), macOS on a Mac mini M4. "Check for updates" reports up to date.

What happens: The X4 Pro joins the crosspoint hotspot. Tapping Sync/APP → System Update on the device shows "Update check failed" every time. No firmware is ever requested.

What works, per /tmp/unlocker-helper.log:

Spoofed DNS queries for ntp.aliyun.com and api-prod.xteink.cc are answered
"answered NTP time sync" appears for the device
The device opens a TCP connection to 192.168.2.1:443 and the TLS handshake starts

What fails:

INFO unlocker_core::http: incoming HTTPS TCP connection client=192.168.2.2:50095 local=192.168.2.1:443
INFO unlocker_core::http: TLS handshake start client=192.168.2.2:50095
ERROR unlocker_core::http: TLS handshake failed client=192.168.2.2:50095 error=received fatal alert: BadCertificate sni_available=false

The same failure repeats on every attempt.

Possible cause (my guess): The device now makes the api-prod.xteink.cc check-update call over HTTPS and rejects the served cert (issued for unlocker.crosspointreader.com). It may be validating the hostname, and the ClientHello carries no SNI.

Question: Is this build known to break the Unlocker? Is there a workaround, or a fix planned?

I can attach the full log if needed.

Activity

  1. itsthisjustin commented on Sep 28, 2026

    @itsthisjustin
    Contributor

    Have not tested this firmware tbh. I'll try to see what I can do

  2. idzeeboo-alt commented on Sep 28, 2026

    @idzeeboo-alt
    Author

    Thanks!

  3. idzeeboo-alt commented on Sep 28, 2026

    @idzeeboo-alt
    Author

    Also, I wanted to mention that as soon as I turn on Wi-Fi sharing on the Mac, the unlocker CLI shows that it has already connected to my X4 Pro, even though I have not yet connected to Wi-Fi on the reader. Not sure if it's just cached somewhere, but thought I'd mention it.

  4. itsthisjustin commented on Sep 29, 2026

    @itsthisjustin
    Contributor

    Ok I'm pushing out an update now. if you could give it a try and report back that would be super helpful

  5. idzeeboo-alt commented on Sep 29, 2026

    @idzeeboo-alt
    Author

    Reproduced on Unlocker 0.2.39 for Mac. Same failure: BadCertificate, sni_available=false, same point in the sequence (DNS spoof → NTP → TLS handshake → reject). NTP and DNS both work again; only the TLS step fails. Reader says "Update check failed".

    INFO unlocker_core::http: incoming HTTPS TCP connection client=192.168.2.2:49404 local=192.168.2.1:443
    INFO unlocker_core::http: TLS handshake start client=192.168.2.2:49404
    ERROR unlocker_core::http: TLS handshake failed client=192.168.2.2:49404 error=received fatal alert: BadCertificate sni_available=false

    I see the cert is new, but the device rejects it. Did the most recent X4 Pro update introduce host name verification, or certificate pinning? I'm just spit-balling ideas here.

  6. itsthisjustin commented on Sep 29, 2026

    @itsthisjustin
    Contributor

    Reproduced on Unlocker 0.2.39 for Mac. Same failure: BadCertificate, sni_available=false, same point in the sequence (DNS spoof → NTP → TLS handshake → reject). NTP and DNS both work again; only the TLS step fails. Reader says "Update check failed".

    INFO unlocker_core::http: incoming HTTPS TCP connection client=192.168.2.2:49404 local=192.168.2.1:443
    INFO unlocker_core::http: TLS handshake start client=192.168.2.2:49404
    ERROR unlocker_core::http: TLS handshake failed client=192.168.2.2:49404 error=received fatal alert: BadCertificate sni_available=false

    I see the cert is new, but the device rejects it. Did the most recent X4 Pro update introduce host name verification, or certificate pinning? I'm just spit-balling ideas here.

    If appeared to just be cert pinning which is why I bought a new cert

  7. itsthisjustin commented on Sep 29, 2026

    @itsthisjustin
    Contributor

    Reproduced on Unlocker 0.2.39 for Mac. Same failure: BadCertificate, sni_available=false, same point in the sequence (DNS spoof → NTP → TLS handshake → reject). NTP and DNS both work again; only the TLS step fails. Reader says "Update check failed".

    INFO unlocker_core::http: incoming HTTPS TCP connection client=192.168.2.2:49404 local=192.168.2.1:443
    INFO unlocker_core::http: TLS handshake start client=192.168.2.2:49404
    ERROR unlocker_core::http: TLS handshake failed client=192.168.2.2:49404 error=received fatal alert: BadCertificate sni_available=false

    I see the cert is new, but the device rejects it. Did the most recent X4 Pro update introduce host name verification, or certificate pinning? I'm just spit-balling ideas here.

    If you had the app before make sure you manually stop the helper in settings and then restart the app so the new one runs

  8. idzeeboo-alt commented on Sep 29, 2026

    @idzeeboo-alt
    Author

    Disabled/re-enabled the helper as suggested. Same result — helper restarted cleanly and reloaded the same cert (not_before=Sep 29 2026), but the device still rejects it with BadCertificate, sni_available=false, same as before.

    INFO unlocker_core::http: TLS handshake start client=192.168.2.2:63902
    ERROR unlocker_core::http: TLS handshake failed client=192.168.2.2:63902 error=received fatal alert: BadCertificate sni_available=false

  9. itsthisjustin commented on Sep 29, 2026

    @itsthisjustin
    Contributor

    Disabled/re-enabled the helper as suggested. Same result — helper restarted cleanly and reloaded the same cert (not_before=Sep 29 2026), but the device still rejects it with BadCertificate, sni_available=false, same as before.

    INFO unlocker_core::http: TLS handshake start client=192.168.2.2:63902 ERROR unlocker_core::http: TLS handshake failed client=192.168.2.2:63902 error=received fatal alert: BadCertificate sni_available=false

    Any chance the clock on your device is wrong? can you first try setting it via a valid OTA update request on real wifi and then try again?

  10. idzeeboo-alt commented on Sep 29, 2026

    @idzeeboo-alt
    Author

    I connected to my regular wi-fi and ran an update. It is offering update 260929 @ 4.1 MB.
    Should I apply it?

  11. itsthisjustin commented on Sep 29, 2026

    @itsthisjustin
    Contributor

    I connected to my regular wi-fi and ran an update. It is offering update 260929 @ 4.1 MB. Should I apply it?

    I wouldnt haha but now try the unlocker now that clock is set

  12. idzeeboo-alt commented on Sep 29, 2026

    @idzeeboo-alt
    Author

    Retried per your suggestion -skipped the 260929 update, fresh Unlocker session. Same result:

    TLS handshake start client=192.168.2.2:55880
    TLS handshake failed client=192.168.2.2:55880 error=received fatal alert: BadCertificate sni_available=false

  13. itsthisjustin commented on Sep 29, 2026

    @itsthisjustin
    Contributor

    Retried per your suggestion -skipped the 260929 update, fresh Unlocker session. Same result:

    TLS handshake start client=192.168.2.2:55880 TLS handshake failed client=192.168.2.2:55880 error=received fatal alert: BadCertificate sni_available=false

    Can you send me the full log?

  14. idzeeboo-alt commented on Sep 29, 2026

    @idzeeboo-alt
    Author
  15. idzeeboo-alt commented on Sep 29, 2026

    @idzeeboo-alt
    Author

    FWIW, I tried the unlocker on my Macbook Pro and got the exact same error.

  16. 3 remaining items

  17. idzeeboo-alt commented on Sep 30, 2026

    @idzeeboo-alt
    Author

    Ok, I tried it both ways: Upgraded Unlocker to newest version (0.2.40), stopped the helper, changed the HTTP force setting, restarted helper, connected, attempted update - with and without HTTP forced. Both failed with the same message on the reader as before. Here are the logs from each attempt.

    With_HTTP_Forced.txt

    Without_HTTP_Forced.txt

  18. idzeeboo-alt commented on Oct 1, 2026

    @idzeeboo-alt
    Author

    Do you think I should try processing the current stock OS update and try again? If you're still digging in on this, I don't want to mess up the work we've done so far. Let me know what you think.

  19. itsthisjustin commented on Oct 1, 2026

    @itsthisjustin
    Contributor

    Do you think I should try processing the current stock OS update and try again? If you're still digging in on this, I don't want to mess up the work we've done so far. Let me know what you think.

    Yes please try

  20. idzeeboo-alt commented on Oct 2, 2026

    @idzeeboo-alt
    Author

    Tested 0.2.40 against stock 100126, both modes:

    force-HTTP: device never attempts a connection at all — no incoming request logged on port 80, even after DNS resolves. Looks like the device only tries HTTPS and doesn't fall back.
    HTTPS re-enabled: identical failure as before — BadCertificate, sni_available=false, same point in the handshake.

    So neither approach gets past this on the current stock firmware. I suspect the device needs something specific from the served certificate (or the handshake) that it isn't getting.

    • I also tried the "repair network Mac settings" in the advanced options *

    unlocker-0.2.40-force-http-100126.txt
    unlocker-0.2.40-https-100126.txt

  21. idzeeboo-alt commented on Oct 3, 2026

    @idzeeboo-alt
    Author

    Confirmed on newest stock 261003_01 (installed via real update): same failure. One cosmetic change — this build's NTP query went to ntp.tencent.com instead of ntp.aliyun.com, otherwise identical sequence and identical BadCertificate/sni_available=false result. Four stock versions now tested (260924, 260929, 100126, 261003_01) with the same outcome.

  22. idzeeboo-alt commented on Oct 5, 2026

    @idzeeboo-alt
    Author

    FYI - Also tried Windows 11 tonight (Unlocker 0.2.38, which loads the older Aug 4 cert), on stock 261003_01. Same result: the device connects to 443 and rejects the cert with BadCertificate, sni_available=false. So the failure reproduces on macOS (two machines) and Windows, with both the Aug and Sep 29 certs.

  23. idzeeboo-alt commented on Oct 5, 2026

    @idzeeboo-alt
    Author

    Hello Justin,
    With all that I've tried on my end, my assessment is that during the update, the reader queries DNS for api-prod.xteink.cc and connects to port 443. The app serves a hardcoded TLS certificate issued to “unlocker.crosspointreader.com”. The reader's TLS client detects the SAN mismatch against api-prod.xteink.cc (or detects a non-trusted root CA) and aborts the connection. Because sni_available=false is sent by the client, no SNI negotiation can occur. I also think the X4 Pro firmware has https:// hardcoded for the update check; when port 443 is unbound (when I try to force http in the advanced settings), the reader receives a TCP connection refused and does not fall back to plain HTTP on port 80.
    It is likely something XTE Ink did on their end to tighten security in recent releases (just my guess). Is anyone else with the X4 Pro experiencing these issues as far as you know? Or is it just me - LOL.
    Thanks!

  24. itsthisjustin commented on Oct 5, 2026

    @itsthisjustin
    Contributor

    I dont think most users are trying to unlock from licorice is all. Thankfully. I have no idea how to get around this right now. Ideas?

  25. idzeeboo-alt commented on Oct 5, 2026

    @idzeeboo-alt
    Author

    Potential workarounds:
    -WebUSB / WebSerial Flasher: Is it possible to use the Chromium WebSerial/WebUSB tool via the pogo-pin cable for devices on Licorice? Or does the Licorice bootloader disable / lock the USB flashing interface completely on the X4 Pro?
    -Downgrade to pre-Licorice stock: I think Xteink hosts full rollback / unbrick binaries via their web flasher (xtcloud.xteink.cc/app/firmware-flash) or an SD recovery package that would put the device back on an earlier build where the OTA proxy still works?
    -Custom Root CA Injection: If there is any accessible partition, config file, or SD card path where Licorice looks for custom CAs, we could trust the proxy cert, though that seems unlikely without prior root access.

    If WebSerial isn't an option and the bootloader is locked to encrypted OTA only, then unless someone dumps the Xteink private key or finds an unauthenticated exploit in the Licorice parser, Licorice users might be locked out of the OTA proxy path for now.

  26. idzeeboo-alt commented on Oct 5, 2026

    @idzeeboo-alt
    Author

    HEY!!!! I was just able to flash it to the latest Crosspoint software using the serial browser method!

    Image

    Devices running XT Licorice can bypass the OTA proxy certificate block entirely by flashing directly over WebSerial / browser flasher via the pogo-pin cable. (Wish I would have tried that last week! hahahaha)

  27. fsocietyipa commented on Oct 6, 2026

    @fsocietyipa

    HEY!!!! I was just able to flash it to the latest Crosspoint software using the serial browser method!

    Image Devices running XT Licorice can bypass the OTA proxy certificate block entirely by flashing directly over WebSerial / browser flasher via the pogo-pin cable. (Wish I would have tried that last week! hahahaha)

    Do you have the chinese version or the global one?

  28. idzeeboo-alt commented on Oct 6, 2026

    @idzeeboo-alt
    Author

    Global

  29. khab-el commented on Oct 20, 2026

    @khab-el

    i have same issue with tls handshake but i have chinese version and can't flash via pogo-pin cable

  30. itsthisjustin commented on Oct 20, 2026

    @itsthisjustin
    Contributor

    Looks like latest Licorice update now has SD flashing. I also just got off the phone with xteink and they shared some very positive news as it pertains to locking devices just an fyi. https://www.reddit.com/r/XTEINK/s/xRCab3StsL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions