Last week I had another error while using UTL_HTTP from an Oracle database to fetch a web page: ORA-28860 Fatal SSL error. The server was previously using http, and then began forwarding to https.

After updating the URL to use https (in case the forwarding was the problem), my first thought was that this is another symptom of a missing trusted root certificate. So I added the certificate to the Oracle Wallet, but that had no effect:

SELECT utl_http.request('https://test.com/page', NULL, 'file:/path/to/wallet', 'WalletPassword') FROM dual * Error at line 1 ORA-29273: HTTP request failed ORA-28860: Fatal SSL error ORA-06512: at "SYS.UTL_HTTP", line 1491 ORA-06512: at line 1

So my working hypothesis was that the fatal error occurs during SSL negotiation prior to validation of the server’s certificate, possibly to do with supported SSL version or cipher suites. One of the few references to this problem supported this theory, although the two specific issues mentioned at the end (to do with SSL version) did not apply in my case.

With that in mind, I used a standard tool to see what the server supports:

wget https://testssl.sh/testssl.sh chmod a+x testssl.sh ./testssl.sh https://test.com/

The output is comprehensive; this is the pertinent section:

--> Testing protocols (via sockets except TLS 1.2 and SPDY/NPN) SSLv2 not offered (OK) SSLv3 not offered (OK) TLS 1 offered TLS 1.1 offered TLS 1.2 offered (OK) SPDY/NPN not offered --> Testing ~standard cipher lists Null Ciphers not offered (OK) Anonymous NULL Ciphers not offered (OK) Anonymous DH Ciphers not offered (OK) 40 Bit encryption not offered (OK) 56 Bit encryption Local problem: No 56 Bit encryption configured in /usr/bin/openssl Export Ciphers (general) not offered (OK) Low (<=64 Bit) not offered (OK) DES Ciphers not offered (OK) Medium grade encryption not offered (OK) Triple DES Ciphers offered (NOT ok) High grade encryption offered (OK) --> Testing (perfect) forward secrecy, (P)FS -- omitting 3DES, RC4 and Null Encryption here PFS is offered (OK) ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA --> Testing server preferences Has server cipher order? yes (OK) Negotiated protocol TLSv1.2 Negotiated cipher ECDHE-RSA-AES128-GCM-SHA256, Cipher order TLSv1: ECDHE-RSA-AES128-SHA ECDHE-RSA-AES256-SHA AES256-SHA AES128-SHA DES-CBC3-SHA TLSv1.1: ECDHE-RSA-AES128-SHA ECDHE-RSA-AES256-SHA AES256-SHA AES128-SHA DES-CBC3-SHA TLSv1.2: ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-SHA256 AES256-SHA AES128-SHA DES-CBC3-SHA

With TLSv1.2 supported, this should be fine with Oracle 12c. The next step, is to see what UTL_HTTP offers when it makes the connection to the server. I couldn’t find any documentation on this, so I thought it would be fun (I don’t get out much) to look at the packets on the network to see what’s going on.

$ sudo tcpdump -i eth0 -w ssl_dump.out tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes ^C158 packets captured 158 packets received by filter 0 packets dropped by kernel

After starting this, and before interrupting it with ^C, I used another session to call UTL_HTTP as above. Then I opened the output file in Wireshark, and found the SSL ClientHello message:

Secure Sockets Layer TLSv1.2 Record Layer: Handshake Protocol: Client Hello Content Type: Handshake (22) Version: TLS 1.2 (0x0303) Length: 107 Handshake Protocol: Client Hello Handshake Type: Client Hello (1) Length: 103 Version: TLS 1.2 (0x0303) Random GMT Unix Time: Sep 9, 2016 21:01:14.000000000 GMT Daylight Time Random Bytes: cabc488d10a2b6be6aa7ef0777628f62c9a100dd8d878998... Session ID Length: 0 Cipher Suites Length: 32 Cipher Suites (16 suites) Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d) Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c) Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d) Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c) Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024) Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023) Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a) Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009) Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035) Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f) Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a) Cipher Suite: TLS_RSA_WITH_RC4_128_SHA (0x0005) Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004) Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff) Compression Methods Length: 1 Compression Methods (1 method) Compression Method: null (0) Extensions Length: 30 Extension: signature_algorithms Type: signature_algorithms (0x000d) Length: 26 Signature Hash Algorithms Length: 24 Signature Hash Algorithms (12 algorithms) Signature Hash Algorithm: 0x0201 Signature Hash Algorithm Hash: SHA1 (2) Signature Hash Algorithm Signature: RSA (1) Signature Hash Algorithm: 0x0301 Signature Hash Algorithm Hash: SHA224 (3) Signature Hash Algorithm Signature: RSA (1) Signature Hash Algorithm: 0x0401 Signature Hash Algorithm Hash: SHA256 (4) Signature Hash Algorithm Signature: RSA (1) Signature Hash Algorithm: 0x0501 Signature Hash Algorithm Hash: SHA384 (5) Signature Hash Algorithm Signature: RSA (1) Signature Hash Algorithm: 0x0601 Signature Hash Algorithm Hash: SHA512 (6) Signature Hash Algorithm Signature: RSA (1) Signature Hash Algorithm: 0x0202 Signature Hash Algorithm Hash: SHA1 (2) Signature Hash Algorithm Signature: DSA (2) Signature Hash Algorithm: 0x0403 Signature Hash Algorithm Hash: SHA256 (4) Signature Hash Algorithm Signature: ECDSA (3) Signature Hash Algorithm: 0x0503 Signature Hash Algorithm Hash: SHA384 (5) Signature Hash Algorithm Signature: ECDSA (3) Signature Hash Algorithm: 0x0203 Signature Hash Algorithm Hash: SHA1 (2) Signature Hash Algorithm Signature: ECDSA (3) Signature Hash Algorithm: 0x0303 Signature Hash Algorithm Hash: SHA224 (3) Signature Hash Algorithm Signature: ECDSA (3) Signature Hash Algorithm: 0x0603 Signature Hash Algorithm Hash: SHA512 (6) Signature Hash Algorithm Signature: ECDSA (3) Signature Hash Algorithm: 0x0101 Signature Hash Algorithm Hash: MD5 (1) Signature Hash Algorithm Signature: RSA (1)

and the server’s response:

Secure Sockets Layer TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure) Content Type: Alert (21) Version: TLS 1.2 (0x0303) Length: 2 Alert Message Level: Fatal (2) Description: Handshake Failure (40)

Now as far as I can see, none of the 16 cipher suites presented by UTL_HTTP are in the list supported by the server, and so the Fatal SSL error is quite correct.

The question now, is what can I do about it? I can’t influence the external server, and I can’t find anything in the Oracle documentation to change the behaviour of UTL_HTTP.

My only attempt so far has been to patch up to the latest PSU (12.1.0.2.160719), but alas that didn’t make any difference.

The only thing I can think of trying next is to replace the call to UTL_HTTP with some Java in the database, or to somehow call out to wget or curl (which work fine to the same site).

## Platform Information

The material in this article was most recently tested against Oracle 12.1.0.2.160719 on 64-bit Linux.