tags:

views:

501

answers:

1

I'm accessing an internal database using Matlab's urlread command, everything was working fine until the service was moved to a secure server (i.e. with an https address rather than an http address). Now urlread no longer successfully retrieves results (It gives an error: "Error downloading URL. Your network connection may be down or your proxy settings improperly configured"). I believe the problem is that the service is using an invalid digital certificate since if I try to access the resource directly in a web browser I get "untrusted connection" warning which I am able to pass through by adding the site to an Exception list. urlread doesn't have an obvious way of handling this problem.

Under the hood urlread is using Java to access web resources, and the error is thrown at this line:

inputStream = urlConnection.getInputStream;

where urlConnection is a Java object: sun.net.www.protocol.https.HttpsURLConnectionImpl.

Anyone suggest a workaround for this problem?

+3  A: 

Consider this MATLAB code:

javaclasspath('C:\MATLAB\MyJavaClasses')
dl = javaObject('com.stackoverflow.Downloader');
page = dl.getData('https://msp.f-secure.com/web-test/common/test.html');
str = char(page)

which uses the following Java class:

package com.stackoverflow;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class Downloader {
    public static String getData(String address) throws Exception {
     TrustManager[] trustAllCerts = new TrustManager[] {
      new X509TrustManager() {
       public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
       public void checkClientTrusted(X509Certificate[] certs, String authType) {}
       public void checkServerTrusted(X509Certificate[] certs, String authType) {}
      }
     };

     SSLContext sc = SSLContext.getInstance("SSL");
     sc.init(null, trustAllCerts, new java.security.SecureRandom());
     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

     URL page = new URL(address);
     HttpURLConnection conn = (HttpURLConnection) page.openConnection();
     BufferedReader buff = new BufferedReader(new InputStreamReader(conn.getInputStream()));

     String line;
     StringBuffer text = new StringBuffer();
     while ( (line = buff.readLine()) != null ) {
      //System.out.println(line);
      text.append(line + "\n");
     }
     buff.close();

     //System.out.println( text.toString() );
     return text.toString();
    }

    public static void main(String[] argv) throws Exception {
     System.out.println( getData("https://msp.f-secure.com/web-test/common/test.html") );
    }
}

I used this page as reference: Disabling Certificate Validation in an HTTPS Connection

Unfortunately I couldnt test it myself as I didnt find an invalid certificate URL. Let us know if this works for you...

Amro
Thanks Amro - that appears to be working for a test case with an invalid certificate! My Java competence is a bit minimal and I ended up taking the package statement out to get it to work, possibly if I put stuff into the right directory structure I wouldn't need to do that.
Ian Hopkinson