Enabling TLSv1.2 on CentOS 5
18 June 2018
We have a legacy IVR (Interactive Voice Response) software running an Asterisk PBX Server. It executes AGI (Asterisk Gateway Interface) compliant protocol to launch external programs written in Python to control telephony channel, play audio, read DTMF (Dual Tone Multi Frequency) digits, etc. We ran into an issue when the payment gateway stopped supporting lower versions of TLS (Transport Layer Security). It requires TLSv1.2 as minimum version.
Issue
$ curl -Ivvv https://secure.payment.com
* About to connect() to secure.payment.com port 443
* Trying 185.n.n.n... connected
* Connected to secure.payment.com (185.n.n.n) port 443
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSLv2, Client hello (1):
Unknown SSL protocol error in connection to secure.payment.com:443
* Closing connection #0
curl: (35) Unknown SSL protocol error in connection to secure.payment.com:443
Workaround
You need to build OpenSSL and cURL using your current CentOS.
$ wget https://www.openssl.org/source/openssl-1.0.2a.tar.gz --no-check-certificate
Resolving www.openssl.org... 23.214.162.69, 2a02:26f0:f6:199::c1e, 2a02:26f0:f6:1be::c1e
Connecting to www.openssl.org|23.214.162.69|:443... connected.
WARNING: cannot verify www.openssl.org's certificate, issued by `/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3':
Unable to locally verify the issuer's authority.
HTTP request sent, awaiting response... 200 OK
Length: 5262089 (5.0M) [application/x-gzip]
Saving to: `openssl-1.0.2a.tar.gz'
100%[============================================================>] 5,262,089 3.14M/s in 1.6s
$ wget http://curl.haxx.se/download/curl-7.42.1.tar.gz
Resolving curl.haxx.se (curl.haxx.se)... 151.101.2.49, 151.101.66.49, 151.101.130.49, ...
Connecting to curl.haxx.se (curl.haxx.se)|151.101.2.49|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://curl.haxx.se/download/curl-7.42.1.tar.gz [following]
Connecting to curl.haxx.se (curl.haxx.se)|151.101.2.49|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 4291533 (4.1M) [application/x-gzip]
Saving to: ‘curl-7.42.1.tar.gz’
100%[===========================================================>] 4.09M 4.33MB/s in 0.9s
Build OpenSSL
$ ./config -fpic shared
Operating system: x86_64-whatever-linux2
Configuring for linux-x86_64
Configuring for linux-x86_64
no-ec_nistp_64_gcc_128 [default] OPENSSL_NO_EC_NISTP_64_GCC_128 (skip dir)
no-gmp [default] OPENSSL_NO_GMP (skip dir)
no-jpake [experimental] OPENSSL_NO_JPAKE (skip dir)
no-krb5 [krb5-flavor not specified] OPENSSL_NO_KRB5
no-libunbound [experimental] OPENSSL_NO_LIBUNBOUND (skip dir)
no-md2 [default] OPENSSL_NO_MD2 (skip dir)
no-rc5 [default] OPENSSL_NO_RC5 (skip dir)
no-rfc3779 [default] OPENSSL_NO_RFC3779 (skip dir)
no-sctp [default] OPENSSL_NO_SCTP (skip dir)
no-ssl-trace [default] OPENSSL_NO_SSL_TRACE (skip dir)
no-store [experimental] OPENSSL_NO_STORE (skip dir)
no-unit-test [default] OPENSSL_NO_UNIT_TEST (skip dir)
no-zlib [default]
no-zlib-dynamic [default]
...
Configured for linux-x86_64.
$ sudo make && make build
...
cp libcrypto.pc /usr/local/ssl/lib/pkgconfig
chmod 644 /usr/local/ssl/lib/pkgconfig/libcrypto.pc
cp libssl.pc /usr/local/ssl/lib/pkgconfig
chmod 644 /usr/local/ssl/lib/pkgconfig/libssl.pc
cp openssl.pc /usr/local/ssl/lib/pkgconfig
chmod 644 /usr/local/ssl/lib/pkgconfig/openssl.pc
$ sudo /sbin/ldconfig
Build cURL
$ sudo ./configure --with-ssl=/usr/local/ssl
...
configure: Configured to build curl/libcurl:
curl version: 7.42.1
Host setup: x86_64-unknown-linux-gnu
Install prefix: /usr/local
Compiler: gcc
SSL support: enabled (OpenSSL)
SSH support: no (--with-libssh2)
zlib support: enabled
GSS-API support: no (--with-gssapi)
TLS-SRP support: enabled
resolver: default (--enable-ares / --enable-threaded-resolver)
IPv6 support: no (--enable-ipv6)
Unix sockets support: enabled
IDN support: no (--with-{libidn,winidn})
Build libcurl: Shared=yes, Static=yes
Built-in manual: enabled
--libcurl option: enabled (--disable-libcurl-option)
Verbose errors: enabled (--disable-verbose)
SSPI support: no (--enable-sspi)
ca cert bundle: /etc/pki/tls/certs/ca-bundle.crt
ca cert path: no
LDAP support: no (--enable-ldap / --with-ldap-lib / --with-lber-lib)
LDAPS support: no (--enable-ldaps)
RTSP support: enabled
RTMP support: no (--with-librtmp)
metalink support: no (--with-libmetalink)
HTTP2 support: disabled (--with-nghttp2)
Protocols: DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS POP3 POP3S RTSP SMB SMBS SMTP SMTPS TELNET TFTP
$ sudo make && make install
Test the workaround
curl -Ivvv https://secure.payment.com
* Trying 185.n.n.n...
* Connected to secure.payment.com (185.n.n.n) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* TLSv1.2, TLS Unknown, Unknown (22):
* TLSv1.2, TLS handshake, Client hello (1):
* SSLv2, Unknown (22):
* TLSv1.2, TLS handshake, Server hello (2):
* SSLv2, Unknown (22):
* TLSv1.2, TLS handshake, CERT (11):
* SSLv2, Unknown (22):
* TLSv1.2, TLS handshake, Server key exchange (12):
* SSLv2, Unknown (22):
* TLSv1.2, TLS handshake, Server finished (14):
* SSLv2, Unknown (22):
* TLSv1.2, TLS handshake, Client key exchange (16):
* SSLv2, Unknown (20):
* TLSv1.2, TLS change cipher, Client hello (1):
* SSLv2, Unknown (22):
* TLSv1.2, TLS handshake, Finished (20):
* SSLv2, Unknown (20):
* TLSv1.2, TLS change cipher, Client hello (1):
* SSLv2, Unknown (22):
* TLSv1.2, TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: jurisdictionC=GB; businessCategory=Private Organization; serialNumber=03539217; C=GB; ST=London; L=London; O=Pay360 Limited; CN=secure.payment.com
* start date: 2017-03-16 00:00:00 GMT
* expire date: 2019-03-16 23:59:59 GMT
* subjectAltName: secure.payment.com matched
* issuer: C=US; O=Symantec Corporation; OU=Symantec Trust Network; CN=Symantec Class 3 EV SSL CA - G3
* SSL certificate verify ok.
Next challenge is updating Python. Having curl
working can be a good fallback if Python 2.7.9 upgrade fails.
Credit goes to this blog