Das.Linux at gmx.de
Tue Jun 13 21:35:22 UTC 2017
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:
for our client to see what went wrong, or should we just always
when something is wrong? */
/* ... */
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).
2. Certificates not having sAN (and cn only) is DEPRECATED.
3. If a certificate has multiple sAN/dNSName, any of them is a potential match.
4. Wildcards (*) SHALL only appear as whole name parts, and have other restrictions.
- `*.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)
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
certificateName match: peerName
on the image side.
- 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?
More information about the Vm-dev