All I gathered from this blog post was “OpenSSL has incomprehensible error codes or the entire cert ecosystem is too complicated”.
Correction: “OpenSSL has incomprehensible error codes AND the entire cert ecosystem is too complicated”
I’m currently trying to figure out why connections between older stunnel/openssl versions and newer versions of the same software aren’t working. My current hypothesis is that the certificates used are “invalid” according to the newer versions, and because of this they refuse to use them as client certificates - but they do this silently, so the other end just sees a connection with no client certificate. Yum yum.
While the cert ecosystem is complicated, openssl’s bad errors are what make it incomprehensible I think. I’ve spent a fair amount of time debugging TLS in different situations. OpenSSL and stunnel was sufficiently opaque and hard to debug that we ended up replacing it entirely with a version written in Go, which has a TLS stack that actually gives half-reasonable error messages.
Absolute shot in the dark but how long are your keys? OpenSSL recently started erroring out when asked to use short keys, and that messed me up for a while. 2048 bit minimum for RSA, don’t know about any of the others off the top of my head. My code didn’t fail silently, but I was using Python and for all I know I only ever saw error messages because of that. Feel free to message me if you hit a dead end or just want to chat, I can’t promise I can help but happy to try.
That’s one possible problem, thanks for the suggestion! One part of the system uses 1024 bit RSA keys, I think.
Finding out about this kind of requirement seems to be on the level of “oh, I saw a comment on a Stack Overflow post about something remotely related”… Perhaps I just don’t know where to look.
I actually ran into this problem last week and my takeaway was that Google’s server expects a server name indicator (SNI) in https requests; don’t know how familiar you are with TLS, but SNI can be sent by the client during negotiation to indicate which certificate the server should use. Handy for servers that host multiple domains and need to know which certificate to present before they receive a Host header. Anyway, if Google doesn’t get SNI it apparently falls back to a self-signed certificate that has this message buried in it, since it doesn’t know to use the www.google.com certificate or whatever.
Edit: None of that actually justifies this outcome. Google’s doing something weird and nonstandard to draw attention to what it perceives as a defect (and probably 99% of the time, they’re right), because there’s no official way to raise the error they want to raise. How much of that is on Google and how much of that is on the ecosystem is debatable, but it creates a headache when the solution to “The server uses a self-signed certificate!” is “Send SNI in your client”, and also there’s no good way to look this up.
In the age of cloud/CDNs everywhere, it’s safest to treat SNI as a hard requirement. Take Cloudfront as an example:
% openssl s_client -connect cf.feitsui.com:443
4559363692:error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/ssl/ssl_pkt.c:386:
no peer certificate available
No client certificate CA names sent
SSL handshake has read 5 bytes and written 0 bytes
% openssl s_client -connect cf.feitsui.com:443 -servername cf.feitsui.com
depth=4 C = US, O = "Starfield Technologies, Inc.", OU = Starfield Class 2 Certification Authority
depth=3 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2
depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
depth=0 CN = *.cloudping.cloud
It’s only really ancient clients that don’t support SNI - think IE on XP and Android 1, maybe? As a result you find SNI is often a requirement or CDNs give the option to pay extra for the dedicated IP you need for non-SNI connections. I know Cloudfront charges $600 a month for dedicated IPs/SSL certificates, and I know others (Fastly, Cloudflare, etc.) charge as well.
And your server would have to be dangerously old (think “pre-dating TLS”) to not support it.
Android got SNI support around 2011 in versions 3 and later. Internet Explorer on Windows XP would have been the last holdout. I can’t imagine either of those can effectively use the internet today, especially given they’re both TLS 1.0 only clients and many servers require TLS 1.2 or later; at least anything under PCI-DSS scope.