[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 363
  • Last Modified:

Reading page through HTTPS from server with expired certificate

Does anybody know if it is possible to read a page from HTTPS server on which is expired certificate using JSSE ?

I've found HttpClient from apache project (http://jakarta.apache.org/commons/httpclient/sslguide.html) which is able to read from server with self signed cert, but when cert is expired it throws exception.

I'm also forced to use JDK 1.3.1.
0
MirecXP
Asked:
MirecXP
  • 6
  • 5
  • 3
2 Solutions
 
bloodredsunCommented:
You could use an HttpUrlConnection and then override the x509 manager so that it accepts all certificates (even self-signed and expired ones)
0
 
neonlinesCommented:
If u use HttpUrlConnection, u can not read a page from HTTPS server. U can read the page by using HttpUrlConnection, if and only if, the server is listening in HTTP port also.

If the server is listening only HTTPS port (U can configure both the things), u have to use only HttpsUrlConnection and for that u need only Valid certificate.

It's not possible to read a page from HTTPS server on which is expired certificate using JSSE
0
 
bloodredsunCommented:
>> If u use HttpUrlConnection, u can not read a page from HTTPS server

Try this method:

      /**
       * reads a servlet,jsp or html page via https. Using an all accepting X509 (certificate) manager
       * it then communicates using a standard HttpURLConnection call that communicates using a POST request.
       * The method takes an argument of the URL including the protocol "https" and a second
       * argument of a querystring of paramters that is communicated using a POST request
       * @param pURL
       * @param pParameters
       * @return String literal response from pURL
       */
      public static String httpsConnect( String pURL , String pParameters) {
            
            //setConnectionTimeout() ;
            
            StringBuffer sb = new StringBuffer() ;
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[]{
                  new X509TrustManager() {
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                              return null;
                        }
                        public void checkClientTrusted(
                                    java.security.cert.X509Certificate[] certs, String authType) {
                        }
                        public void checkServerTrusted(
                                    java.security.cert.X509Certificate[] certs, String authType) {
                        }
                  }
            };
            // Install the all-trusting trust manager
            try {
                  SSLContext sc = SSLContext.getInstance("SSL");
                  sc.init(null, trustAllCerts, new java.security.SecureRandom());
                  HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            } catch (Exception e) {
            }
      
            // Now you can access an https URL without having the certificate in the truststore
            try {
                  //connect
                  URL u = new URL( pURL  );
                  
                  HttpURLConnection huc = (HttpURLConnection) u.openConnection();
                  huc.setRequestMethod( "POST" );
                  huc.setDoOutput( true );
                  
                  
                  //Add Parameters via DataOutputStream
                  DataOutputStream printout = new DataOutputStream(huc.getOutputStream ());
                  String content = pParameters ;
                  printout.writeBytes( content );
                  printout.flush ();
                  printout.close ();
                  _LOGGER.info( "added "+pParameters+ " and connecting to " + pURL);
                  
                  //Perform the httpurlconnection
                  huc.connect();
                  
                  //Read the returned input into a StringBuffer
                  BufferedReader br = new BufferedReader(new InputStreamReader(huc.getInputStream()));
                  int b = 0;
                  while((b = br.read()) != -1) {
                        sb.append((char)b);
                  }
                  br.close();
                  // disconnect HttpURLConnection
                  huc.disconnect() ;
            }
            catch (Exception e){      
                  System.out.println("error") ;
                  e.printStackTrace(); }
            return sb.toString() ;
      }//end httpsConnect
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
neonlinesCommented:
bloodredsun :

The method httpsConnect is not abstract method

So, new X509TrustManager() news to override 2 more methods isServerTrusted() and isClientTrusted()

Both the methods should validate ur certificate (!?)

What I am trying to say is if ur server is not cinfigured to listen HTTP in a perticular port and it's listening only in HTTPS, u can not use HttpURLConnection

In this case, I think u will get a error message as "java.net.UnknownHostException"

Btw, I tried ur code and I got the same exception java.net.UnknownHostException

Am I making any mistakes?


0
 
MirecXPAuthor Commented:
Got it!

Dummy trust manager should look like this one for JDK1.3.1 with standalone JSSE
(bloodredsun is using JSSE integrated in JDK1.4.2):

class DummyX509TrustManager() {
    public boolean isClientTrusted(java.security.cert.X509Certificate[] x509CertificateArray) {
       return true;
    };
    public boolean isServerTrusted(java.security.cert.X509Certificate[] x509CertificateArray) {
      return true;
    };
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
      return null;
    }
}

After registering this manager, i can do it !

bloodredsun :
Is it possile to use HttpURLConnection for GET method also ?
0
 
bloodredsunCommented:
>>Is it possile to use HttpURLConnection for GET method also ?

AFAIK yes, there's no reason you shouldn't be able to.
0
 
MirecXPAuthor Commented:
It works even if the server does not listen on port 80, but only on 443 port.

Now I have other problem:
Do you think is it possible to check the page only ONCE and then to say  
whether cert was valid or not
and whether cert was not self signed
and to check also the page content (but the content should be checked also when the cert was not valid and/or was self signed)
0
 
MirecXPAuthor Commented:
>> >>Is it possile to use HttpURLConnection for GET method also ?
>> 
>> AFAIK yes, there's no reason you shouldn't be able to.

I've tried to set it by
  huc.setRequestMethod( "GET" );

but it still requests using POST method.
0
 
neonlinesCommented:
>> It works even if the server does not listen on port 80, but only on 443 port.

port 80 is default port and it's not open for common access (In general)

>> Now I have other problem:

Add the following line

System.setProperty("javax.net.debug","all");

and u can find all the validation with respsect to SSL handshaking (All ur doubts can check in the console debug message)
0
 
neonlinesCommented:
>> but it still requests using POST method.

using setRequestMethod(), u can set all the defiled methods (GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE)

But, it's subject to protocol restrictions. The default method is GET.

 
0
 
neonlinesCommented:
defiled  = defined
0
 
MirecXPAuthor Commented:
>> Add the following line
>> System.setProperty("javax.net.debug","all");

Thanks, but I need to check it in the code.
I want to monitor the configured pages and I need to decide, wheter I'll trigger some reaction if the cert is not valid, if it is self signed and/or if the page doesn't fulfill content check criteria.

And I don't want to try to check the page 3 times for it, but I don't know if it's possible in a simple way. Maybe I'll need to implement some kind of listener in my own TrustManager...
0
 
neonlinesCommented:
MirecXP :

U no need to check the page for 3 times. The SSL handshaking checks automatically all ur conditions. There are 7 steps in SSL handchaking. After completing all the steps in successful, then only, the server will allow u to access the page.

But, for that u have to use HttpsURLConnection not HttpURLConnection.

If u need referemce for HttpsURLConnection check the following code:


import java.io.InputStream;
import java.net.URL;
import java.lang.StringBuffer;

public class Test {

     public static void main(String[] args) {
         
         
          final String HOST       = "https://urhostname.com";
          final String SUFFIX      = "parameters";
                   
          try {
          com.sun.net.ssl.internal.ssl.Provider.install();
          java.security.Security.insertProviderAt(new com.sun.net.ssl.internal.ssl.Provider(), 1);

          URL url = new URL(null, HOST + SUFFIX, new com.sun.net.ssl.internal.www.protocol.https.Handler());
                 javax.net.ssl.HttpsURLConnection conn = null;
                 conn = (javax.net.ssl.HttpsURLConnection) url.openConnection();
          conn.setDoInput(true);
          conn.setDoOutput(true);
          conn.setUseCaches(false);
          conn.setRequestMethod("POST");
          conn.setFollowRedirects(true);

         
             BufferedReader in           = new BufferedReader(new  InputStreamReader(conn.getInputStream()));
               StringBuffer buff           = new StringBuffer();
               
          String inputLine = null;
          while ((inputLine = in.readLine()) != null)
          {
               System.out.println(inputLine);
          }
               
          }
          catch ( Exception e ) {
               System.out.println("error:" + e.toString());
               
          }
         
     }
}

0
 
MirecXPAuthor Commented:
I can use GET method, but it's necessary to remove sending data to connection, as it can be done only when using POST or PUT method:
//huc.setDoOutput( true );
//Add Parameters via DataOutputStream
//DataOutputStream printout = new DataOutputStream(huc.getOutputStream ());
//String content = pParameters ;
//printout.writeBytes( content );
//printout.flush ();
//printout.close ();

Bloodredsun, Thank you for the tip with DummyTrustManager...
Neonlines, thanks for your effort...
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 6
  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now