Bug 7401

Summary: cannot connect from iOS 13 with self signed certificate
Product: ThinLinc Reporter: Pierre Ossman <ossman>
Component: Web AccessAssignee: Pierre Ossman <ossman>
Status: CLOSED FIXED    
Severity: Normal CC: aleta, samuel
Priority: P2 Keywords: aleta_tester, relnotes
Version: trunk   
Target Milestone: 4.11.0   
Hardware: PC   
OS: Unknown   
Acceptance Criteria:
Bug Depends on:    
Bug Blocks: 7394    

Description Pierre Ossman cendio 2019-10-16 13:42:33 CEST
(moved from bug 7394)

We upgraded our iPad from iOS 12 to iOS 13 and now we can no longer connect to machines using self signed certificates, even when following our instruction where the cn is correct and the certificate has been added with full trust.

The normal connections work fine, and it's only the WebSocket connection that fails.

In the browser console we see the error "OSStatus -9807" which means errSSLXCertChainInvalid. Apple's documentation does not go in to details what that might mean.

iOS 13 has some new requirements on certificates though which might be an issue:

https://support.apple.com/en-us/HT210176

We're currently failing these points:

 * We don't set Subject Alternate Name properly

 * Extended Key Usage isn't set

 * Our validity time is too long (3 years)
Comment 1 Pierre Ossman cendio 2019-10-16 13:56:32 CEST
After some testing it turns out that Subject Alternate Name is the critical missing piece. Adding that makes things work.

So we should have a look at updating our make-dummy-cert script.

We should probably try to comply with the other things as well while we're at it.
Comment 7 Pierre Ossman cendio 2019-10-16 16:10:14 CEST
Seems to work fine now.

Tester should make sure the script works with both old and new versions of OpenSSL.
Comment 8 Samuel Mannehed cendio 2019-10-18 16:52:32 CEST
Generating the cert works well on Fedora 30.

Using the dummy cert works great on macOS 10.14:

* Chrome 77   ✓
* Firefox 69  ✓
* Safari 14   ✓

and on iOS 13:

* Safari 13   ✓

and on Android 9:

* Firefox 69  ✓
* Chrome 77   ✓

and on Windows 10:

* IE 11       ✓
* Edge 14     ✓ (aside from bug 5997)
* Firefox 69  ✓
* Chrome 77   ✓

but using the dummy cert does NOT work in Chrome on Fedora 30:

* Chrome 77   ✗
* Firefox 69  ✓
Comment 9 Pierre Ossman cendio 2019-10-21 14:16:02 CEST
So Chrome apparently uses the TLS library from the system, which on Linux means NSS (same as Firefox). However it seems like Firefox does its own certificate verification, whilst Chrome uses the default handler in NSS.

The problem is in how NSS handles Extended Key Usage. It maps the OIDs of that extension in to an internal bit mask (based on a deprecated older extension). However this bit mask has a special bit for CA certificates, and no such equivalent exists in Extended Key Usage.

They way it resolves this is by looking at the Basic Constraints extension and mapping to different bits depending on if it's marked as a CA or not. There is no way you can get both the server and CA bit set at the same time. So it will either consider the subject certificate to have incorrect key usage, or the issuer (same cert, two different checks).[1]

Oddly enough though, omitting the Extended Key Usage means that it is always approved for server usage. That's how we used to have it. But that fails one of the listed requirements from Apple.


Chrome is less upset about the usage bits being wrong for the issuer. It treats it the same as an unknown issuer. Need to check how other browsers behave.


[1] See cert_ComputeCertType() in certdb.c
Comment 10 Pierre Ossman cendio 2019-10-21 14:18:53 CEST
Also note that I managed to get Firefox on Fedora really upset about the certificate as well, citing SEC_ERROR_INADEQUATE_KEY_USAGE, and completely refusing to continue.

That error code is set when the legacy Key Usage bits (not the Extended) are bad. I was not able to figure out why though and the problem magically disappeared after a while.

I did clear out all certificate exceptions before that, but it had no immediate effect. Perhaps it needed some time to take hold.
Comment 11 Pierre Ossman cendio 2019-10-21 14:25:32 CEST
Note that the error code given currently by NSS is SEC_ERROR_INADEQUATE_CERT_TYPE, which Chrome translates to ERR_CERT_INVALID.
Comment 12 Pierre Ossman cendio 2019-10-21 14:27:00 CEST
(In reply to comment #9)
> 
> Chrome is less upset about the usage bits being wrong for the issuer. It treats
> it the same as an unknown issuer. Need to check how other browsers behave.
> 

Dropping the Basic Constraints to make Chrome happen breaks the iOS use case as iOS no longer considers it a CA and you can no longer enable trust for things using it.

So I guess we'll have to drop the Extended Key Usage and hope Apple doesn't make them a hard requirement.
Comment 15 Pierre Ossman cendio 2019-10-22 13:53:15 CEST
Upstream has stated they don't think this is worth fixing. Chrome will most likely be using a different validator before a change to NSS can be widely deployed.

They did provide us with a better workaround though, in the form of Netscape's legacy certificate type.

Seems to work fine now. Tested with Chrome and Firefox on Linux, Safari on iOS and macOS, and IE and Edge on Windows.
Comment 17 Alex Tanskanen cendio 2019-10-23 13:31:43 CEST
(In reply to comment #15)
> 
> Seems to work fine now. Tested with Chrome and Firefox on Linux, Safari on iOS
> and macOS, and IE and Edge on Windows.
>

Retested it on these and it works fine.