[Vm-dev] halp.

Levente Uzonyi leves at caesar.elte.hu
Tue Jun 13 22:13:38 UTC 2017


On Tue, 13 Jun 2017, Tobias Pape wrote:

> 
> Dear all
>
> I'm calling from the ssl-basement, and lo and behold, it's all a mess.
>
> First, the "fun" parts:
> - OSX SSL does not support ALPN (necessary for good HTTP/2, go figure)
> - while we are at picking, OSX SSL, when using via secure transport, does not give you more hints than
>   * trustworthy (+ trustworthy cause you said me so via keychain)
>   * _maybe_ trustworthy
>   * not trustworthy.
>   Here's the gem from their code:
> 	/* ... */
> 				status = errSSLXCertChainInvalid;
>            }
>            /* Do we really need to return things like:
>                   errSSLNoRootCert
>                   errSSLUnknownRootCert
>                   errSSLCertExpired
>                   errSSLCertNotYetValid
>                   errSSLHostNameMismatch
>               for our client to see what went wrong, or should we just always
>               return
>                   errSSLXCertChainInvalid
>               when something is wrong? */
>            break;
>
> 	/* ... */
>     Really, that's the current code. Color me surprised (to put it politely)
>
>
>
> Now the really un-fun part: peer-name validation.
> -------------------------------------------------
>
> It's half-way ok for osx, quite ok for windows but not right and absent for openssl/unix/linux.
>
> Levente set out to make that better two years ago but I stopped him (sorry for blocking this, btw :( )
> Just now I had to close his PR (https://github.com/squeak-smalltalk/squeakssl/pull/3), and I think I'm stuck.
>
> Just HOW can we achieve the following without _massive_ engineering effort, essentially duplicating large parts of libcurl?
>
> **What do we want?**
> --------------------
> Check that we connected to the right peer with the right certificate.
>
> Up to now the idea _was_ to extract the "peer name" from the `CommonName` of whom we contacted.
>
> However, this is completely insufficient because it need things (a) beyond checking the commonName (serverAlternativeName) and (b) sAN has some priorities as per RFT 2818, 3.1 Server Idenitity et al.
>
> Also: What if a cert has multiple names in the CN (yes that is possible) or the sAN (yes, that is even common)?
>
> OK, we hence _must_ ditch the idea to have the "peer name" handed to the image, because we cannot know _which_ one of multiple the image wants… except when we were given a `serverName` previously.
>
> But even then, this is _really_ complex:
>
> 1. If a certificaet has sAN of dNSName type it MUST be used (even if cn is present).

Sounds easy: skip CN when SAN/DNSName is there.

> 2. Certificates not having sAN (and cn only) is DEPRECATED.

Just because it's deprecated, we should still support it, because most 
certificates are probably still like that.

> 3. If a certificate has multiple sAN/dNSName, any of them is a potential match.

Just iterate over them.

> 4. Wildcards (*) SHALL only appear as whole name parts, and have other restrictions.
>   *  Example:
> 		- `*.example.com` is valid, but
> 		- `*x.example.com` is technically valid but practically invalid
> 		- `*example.com` is  technically valid but practically invalid
> 		- `test.*.example.com` is invalid (as per RFC 6125)
> 		- `*.*.example.com` is invalid
> 		- `*`, `*.`, `*.*`, etc. is invalid
>    * Other matching examples:
> 		- `*.example.com` matches `a.example.com` BUT does NOT match `a.b.example.com`
> 		- `example.com` (in the certificate) matches `example.com.` (hostname) (note trailing period) BUT
> 		- `example.com.` (in the certificate) does NOT match `example.com.` (hostname) (note trailing period)
> 		- `example.com` (in the certificate) matches `EXAMPLE.com` (hostname)

This sounds really complicated, but it's just a case-insensitive suffix 
comparison + the remaining part must end with a dot and must not contain 
any other dots. Perhaps the 63 character limit can be enforced, but any 
other checks are probably unnecessary.
The whole thing should take at most 100 lines of platform independent C code.

Perhaps I'm just not seeing something, but this part doesn't sound 
complicated at all. IIRC extracting the necessary data (CN/SAN) took a lot 
more effort.

Levente

> 5. IP Addresses MUT be of type sAN/iPAddress, NOT sAN/dNSName, they MUST match exactly.
>
> Due to 4., name checking is CANNOT as simple as
> ```Smalltalk
> certificateName match: peerName
> ```
> on the image side.
>
> Systems
> -------
> - On openssl/linux/unix, we have to care for _all_ of the above manually.
> - On osx, we have the funny trust thing from above and hence would have to do the checking on our own (which we would get for free if we wouldn't break the connection right before the internal trust evaluation and do that manually)
> - On win32, the trust evaluation is very good, verifying for us the hostname, too, but extracting it for image side hasn't been done.
>
> ===============================================================
>
> To all poor souls still reading, What Shall We Do?
> 	-Tobias


More information about the Vm-dev mailing list