If your application uses Java 1.7 that connects to Oracle Database securely over TCPS (Transmission Control Protocol with SSL), and you keep your security patching up to date, the latest Oracle April 2021 security updates may raise some challenges for you that aren’t clearly documented. This use case is based on the Oracle EBS 12.2 application and database version 18.104.22.168.
After applying the latest security fixes through all the layers, many users complained they were unable to connect the database using JDBC (Java Database Connectivity) over TPCS. Users received various errors which essentially all boil down to this:
Exception occurred connecting to database: IO Error: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
After some extensive troubleshooting (thanks to jdbc-tester) I observed that the problem is around the SSL handshake—it’s not simply happening. Also notice how it’s “Ignoring disabled protocol: TLSv1.”
%% Initialized: [Session-1, SSL_NULL_WITH_NULL_NULL] Allow unsafe renegotiation: false Allow legacy hello messages: true Is initial handshake: true Is secure renegotiation: false Allow unsafe renegotiation: false Allow legacy hello messages: true Is initial handshake: true Is secure renegotiation: false Ignoring disabled protocol: SSLv3 Ignoring disabled protocol: TLSv1 main, handling exception: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) %% Invalidated: [Session-1, SSL_NULL_WITH_NULL_NULL] main, SEND TLSv1.2 ALERT: fatal, description = handshake_failure main, WRITE: TLSv1.2 Alert, length = 2 [Raw write]: length = 7 0000: 15 03 03 00 02 02 28 ......( main, called closeSocket() main, called close() main, called closeInternal(true) 00:41:23.294 [main] ERROR Main - Exception occurred connecting to database: IO Error: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
This is the first change I observed and it comes from an update in jre/lib/security/java.security file delivered with JDK 1.7.0_301—notice TLSv1, TLSv1.1 being in the disabled list:
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \ DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \ include jdk.disabled.namedCurves
Even after removing those parameters things don’t get better—there’s still a connection error. Through further troubleshooting I unearthed a couple of resources including:
- Article from Oracle blog SSL Connection to Oracle DB using JDBC, TLSv1.2.
- Oracle support note: Auto Enabling Of TLS 1.2 With 11.2 JDBC Driver (Doc ID 2546551.1) that lists two patches 29672453 and is applied on top of 19030178.
However neither of them seems to help our case. Also it’s very difficult to apply patches to custom applications if you’re not installing or using an Oracle home—it’s just one ojdbc6.jar library used by Java. The turning point was the Oracle Support note, How To Update the JDBC and UCP Drivers Bundled with WebLogic Server 10.3.6 and 12c (Doc ID 1970437.1), and patch 29705953. The patch delivers ojdbc drivers. Used in conjunction with the Java command line parameter Doracle.net.ssl_version=1.2, these enable connection to the Oracle Database.
Oracle Database perspective
Looking at this problem from a database or listener point of view, there’s nothing much to observe. We didn’t see any changes in ciphers in use or in protocols. The best tool from the command line is OpenSSL. By going through all the protocols and ciphers we couldn’t observe any changes from patched and not patched instances.
[host@local]$ openssl s_client -cipher AES256-SHA -connect scan.local:1522 -tls1 CONNECTED(00000003) verify return:1 --- No client certificate CA names sent -- SSL handshake has read 3723 bytes and written 507 bytes --- New, TLSv1/SSLv3, Cipher is AES256-SHA Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1 Cipher : AES256-SHA Session-ID: B14A9AAEFK03EEA400760587087215C Session-ID-ctx: Master-Key: ** Key-Arg : None Krb5 Principal: None PSK identity: None PSK identity hint: None Start Time: 1620637057 Timeout : 7200 (sec) Verify return code: 0 (ok) ---
Furthermore, connections using SQL*Plus or SQLDeveloper over TPCS also work fine.
Only by observation from traces can we see it appears Oracle listener now defaults to TLSv1.2 as the default protocol. Previously the default was v1.1. However, I couldn’t find any reference of such a change in the Oracle patch release notes. The listener.ora parameter SSL_VERSION actually controls which protocols to enable. In 12.1 the default parameter is undetermined, however in newer versions it’s set to 1.2.
To conclude, given that OpenSSL doesn’t report any handshake issues and SQL*Plus works fine, and adding in our findings, from a Java point of view the problem seems to be the ojdbc drivers. This makes sense as at the time ojdbc6.jar was released TLS_1.2 didn’t even exist so patching was required. The problem is because there are so many versions of ojdbc for various products and Oracle doesn’t keep the latest copy (one available here didn’t work) or versioning, you don’t really know what’s in use.
The best fix would be to use Java 1.8 with the latest ojdbc8.jar—that works out of the box.
However not all applications are so easy to update, especially legacy ones or ones with no real support. As well, in our case each application has its own Java version so for:
- Java 1.7.0_291 prior Apr21 CPU add cmd parameter -Doracle.net.ssl_version=1.2 and use JAR delivered from patch 29705953 to connect CPU patched databases.
- Java 1.7.0_301 Apr21 CPU update java.security to enable tls protocols if connecting non-psu patched database.
Oracle throws these security improvements at users from time to time. The problem is that they’re not always well documented. If the changes in Java could be found somewhere in the release notes or roadmap, the changes on database or listener could not. At least I couldn’t find them.
Also the fact that the majority of custom apps still use Java 1.7 doesn’t play in our favor.
If I had to support an application running Java 1.7 that uses Amazon RDS instances or Oracle OCI over TCPS, I would definitely start to think about how to get the application onto JDK (Java Development Kit) 1.8 before the CPU patches kick in.
If you have any questions or thoughts about this, please leave them in the comments!