Thursday, 29 December 2016

OpenSSL - Tripped and fell on macOS

I was tinkering with a script that I'd written to test HTTPS endpoints: - 

(echo -ne "GET /DecisionService/ws/HelloWorldProject/1.0/HelloWorld?WSDL HTTP/1.0\r\nHost:\r\n\r\n" ; cat) | openssl s_client -connect localhost:443

Specifically it gets a WSDL from an HTTPS endpoint, but that's not important right now.

When I ran it on a macOS Sierra box: -

(echo -ne "GET /index.html HTTP/1.0\r\nHost:\r\n\r\n" ; cat) | openssl s_client -connect

I saw this: -

33208:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:/BuildRoot/Library/Caches/

The target box is running IBM HTTP Server, and is configured only support TLS 1.2, as per this: -

LoadModule ibm_ssl_module modules/
Listen 8443
<VirtualHost *:8443>
SSLProtocolEnable TLSv12
SSLProtocolDisable SSLv2 SSLv3 TLSv10 TLSv11

KeyFile /opt/ibm/HTTPServer/BPM/ssl/keystore.kdb

and I was seeing this: -

[Thu Dec 29 15:52:11 2016] [warn] [client] [7fd354031c20] [4204] SSL0222W: SSL Handshake Failed, No ciphers specified (no shared ciphers or no shared protocols).  [ ->] [15:52:11.000508812] 0ms

in the IHS error_log.

Alas, it seems that the openssl client on macOS doesn't support TLS 1.2, only 1.0, as per this: -

openssl s_client -connect

usage: s_client args

 -host host     - use -connect instead
 -port port     - use -connect instead
 -connect host:port - who to connect to (default is localhost:4433)
 -verify depth - turn on peer certificate verification
 -cert arg     - certificate file to use, PEM format assumed
 -certform arg - certificate format (PEM or DER) PEM default
 -key arg      - Private key file to use, in cert file if
                 not specified but cert file is.
 -keyform arg  - key format (PEM or DER) PEM default
 -pass arg     - private key file pass phrase source
 -CApath arg   - PEM format directory of CA's
 -CAfile arg   - PEM format file of CA's
 -reconnect    - Drop and re-make the connection with the same Session-ID
 -pause        - sleep(1) after each read(2) and write(2) system call
 -showcerts    - show all certificates in the chain
 -debug        - extra output
 -msg          - Show protocol messages
 -nbio_test    - more ssl protocol testing
 -state        - print the 'ssl' states
 -nbio         - Run with non-blocking IO
 -crlf         - convert LF from terminal into CRLF
 -quiet        - no s_client output
 -ign_eof      - ignore input eof (default when -quiet)
 -no_ign_eof   - don't ignore input eof
 -ssl2         - just use SSLv2
 -ssl3         - just use SSLv3
 -tls1         - just use TLSv1
 -dtls1        - just use DTLSv1

If I compare this to a RHEL 6.6 box, I can see that TLS 1.2 *is* supported by later versions of the openssl client: -

openssl s_client -connect

 -ssl2         - just use SSLv2
 -ssl3         - just use SSLv3
 -tls1_2       - just use TLSv1.2
 -tls1_1       - just use TLSv1.1
 -tls1         - just use TLSv1

 -dtls1        - just use DTLSv1

On the Mac, I have this version of openssl : -

openssl version

OpenSSL 0.9.8zh 14 Jan 2016

whereas on RHEL, I have this version: -

openssl version

OpenSSL 1.0.1e-fips 11 Feb 2013

In other words, a more recent version but an older date :-(

For the record, when I run my test on the RHEL box, it does what I'd expect :-)

So, c'mon, Apple, please update openssl :-)


Radu Cadariu said...

check macport or brew, get the newer openssl client, along with some other missing utilities, such as wget, html2text, whatever else they traditionally miss versus rhel and the myriad of other distros

Dave Hay said...

Thanks for the advice. It's not such a problem, as I have plenty of VMs available to use :-)