title: Oracle 11g, HTTPS connection with Java stored procedure using TLSv1.2
body: <p>I have two separated servers running Oracle 11g. </p>
  
  <p>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:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>We have checked patch set and both servers "have" the same patch set installed:</p>
  
  <p>Server A:
  <a href="https://i.stack.imgur.com/YvLzu.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YvLzu.jpg" alt="enter image description here"></a></p>
  
  <p>Server B:
  <a href="https://i.stack.imgur.com/g7o8M.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/g7o8M.jpg" alt="enter image description here"></a></p>
  
  <p>The Java stored procedure is a simple <code>Class</code> 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 <code>System.setProperty("javax.net.debug", "all")</code> to get back some log whats happening.</p>
  
  <p>The source code of Java stored procedure:</p>
  
  <pre><code>    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();
               }
  
      }
  
  }
  </code></pre>
  
  <p>Then have executed this code with PL/SQL:</p>
  
  <pre><code>begin
  dbms_java.set_output(500000);
  p_test_furs;
  end;
  </code></pre>
  
  <p>The connection from server A works and all works fine, but the problem is on server B.</p>
  
  <p>On server "B" I got exception (above) and If comparing the <code>javax.net.debug</code> I noticed this exception:
  <a href="https://i.stack.imgur.com/ELZVk.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ELZVk.jpg" alt="Exception"></a></p>
  
  <p>The certificates on both servers are the same.</p>
  
  <p>Java version on my database is the same:</p>
  
  <p>Server A:</p>
  
  <p><code>select dbms_java.get_ojvm_property(propstring=&gt;'java.version') from dual</code> returns: 1.6.0_191</p>
  
  <p>Server B:</p>
  
  <p><code>select dbms_java.get_ojvm_property(propstring=&gt;'java.version') from dual</code> returns: 1.6.0_191</p>
  
  <p>What can be wrong or what else I can check on the server/database side?</p>