2

I have two separated servers running Oracle 11g.

The servers were patched with Oracle patch sets to upgrade JVM. After the upgrade, I'm able to communicate with external web service using HTTPS and TLSv1.2, but only on server "A". Server "B" gives me error like:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:142)
at FursTestBaza.Test(FursTestBaza:92)

We have checked patch set and both servers "have" the same patch set installed:

Server A: enter image description here

Server B: enter image description here

The Java stored procedure is a simple Class with one static method. This procedure loads certificates from file system and makes a HTTPS connection to specified URL (hardcoded for test purposes). In the source code I have included System.setProperty("javax.net.debug", "all") to get back some log whats happening.

The source code of Java stored procedure:

    CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED INIS_PROD."FursTestBaza" as 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Enumeration;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
public class FursTestBaza {

    static String napaka="";
    public static void Test() 
    {
        try
        {
        String URL = "https://blagajne.fu.gov.si:9003/v1/cash_registers";
        System.out.println("Testiranje povezave na: " + URL);
        System.setProperty("javax.net.debug", "all");

            System.out.println("==================================");
            System.out.println("1");
            KeyStore p12 = KeyStore.getInstance("pkcs12");

            String geslo = "*******"; //private key password

            System.out.println("2");
            p12.load(new FileInputStream(new File("/oracle/orasw/Wallet/Certifikat/Furs/privateCert/FURS-AS_davcne_blagajne.p12")), geslo.toCharArray());
            Enumeration e = p12.aliases();
            String alias = (String) e.nextElement();
            System.out.println("alias certifikata: " + alias);
            //privatni ključ
            Key privateKey = p12.getKey(alias, geslo.toCharArray());

            System.out.println("3");
            //podpis
            Signature podpis = Signature.getInstance("SHA256WithRSA");
            podpis.initSign((PrivateKey) privateKey);

            System.out.println("4");
            //določimo svoj keystore in TLS1.2
            SSLContext sslcontext = SSLContext.getInstance("TLSv1.2");
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            KeyStore ks = KeyStore.getInstance("PKCS12");

            System.out.println("5");
            ks.load(new FileInputStream(new File("/oracle/orasw/Wallet/Certifikat/Furs/privateCert/FURS-AS_davcne_blagajne.p12")), geslo.toCharArray());
            kmf.init(ks, geslo.toCharArray());

            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            Certificate ca = cf.generateCertificate(new FileInputStream(new File("/oracle/orasw/Wallet/Certifikat/Furs/privateCert/blagajne.fu.gov.si.cer")));

            System.out.println("6");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            System.out.println("7");
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(keyStore);

            System.out.println("8");
            TrustManager[] tm = tmf.getTrustManagers();
            sslcontext.init(kmf.getKeyManagers(), tm, null);

            System.out.println("8.1");

            HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());

            System.out.println("9");
            URL url = new URL(URL);
            HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();

            System.out.println("10");
            httpsURLConnection.connect();
            System.out.println("Povezan na: " + URL + ", chiper:" + httpsURLConnection.getCipherSuite());
            System.out.println("Prekinjam povezavo...");
            httpsURLConnection.disconnect();
            System.out.println("Povezava zaprta.");
            }
            catch(Exception e)
             {
                e.printStackTrace();
             }

    }

}

Then have executed this code with PL/SQL:

begin
dbms_java.set_output(500000);
p_test_furs;
end;

The connection from server A works and all works fine, but the problem is on server B.

On server "B" I got exception (above) and If comparing the javax.net.debug I noticed this exception: Exception

The certificates on both servers are the same.

Java version on my database is the same:

Server A:

select dbms_java.get_ojvm_property(propstring=>'java.version') from dual returns: 1.6.0_191

Server B:

select dbms_java.get_ojvm_property(propstring=>'java.version') from dual returns: 1.6.0_191

What can be wrong or what else I can check on the server/database side?

Mikhail Kholodkov
  • 23,642
  • 17
  • 61
  • 78
Ferguson
  • 527
  • 1
  • 11
  • 29
  • Have you tried comparing your keys referenced in your stored procedure to make sure they're the same? Have you checked the root trust store (generally $JAVA_HOME/lib/security/cacerts) on both servers to make sure they're the same? This seems like a keystore issue to me. – Michael Powers Jun 28 '18 at 17:03
  • As suggested already by @MichaelPowers , check that all the files that you try opening with FileInputStream are exactly the same on both servers. – Eugène Adell Jun 28 '18 at 21:00
  • The certificate is the same for server A and B.. Have also tried those certificates on my local PC and it works fine. Does someone know where is located Java on the database server? If I try to call select dbms_java.get_ojvm_property(propstring=>'java.home'), i get: /oracle/orasw/rdb_v11204/javavm/, but there is no Java executable file. – Ferguson Jun 29 '18 at 06:09

0 Answers0