You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Dhanushka Amarakoon <dh...@iil.informatics.lk> on 2007/06/27 10:34:58 UTC

HTTPS Certification problem

 

 
private StringBuffer httpGet(String cmd) {
    Debug.getInstance().printUsingDebug(
        "AptiloHTTPCommand-> httpGet-> START");
 
    int retry = 0;
    StringBuffer returnVal; // = new StringBuffer("");
 
    while (retry <= retryCount) {
      System.setProperty("javax.net.ssl.trustStore", keyStore);
 
      HttpClient httpclient = new HttpClient();
      GetMethod get = new GetMethod(cmd);
      returnVal = new StringBuffer("");
      System.out.println("COMMAND : " + cmd);
 
      HttpMethodParams httpParams = new HttpMethodParams();
      httpParams.setSoTimeout(httpTimeout);
      get.setParams(httpParams);
 
      try {
        int result = httpclient.executeMethod(get); // Point where keyStore
is initialized.
        int statusCode = get.getStatusCode();
        System.out.println("Sent at " +
                           DateAndTime.returnDateAndTime(System.
            currentTimeMillis()));
        System.out.println("STATUS CODE OF GET METHOD:" + statusCode);
        System.out.println("\nResult is :\n---");
 
        returnVal = new StringBuffer(get.getResponseBodyAsString());
        System.out.println(returnVal);
        System.out.println("---\n");
 
        get.releaseConnection();
        Debug.getInstance().printUsingDebug(
            "AptiloHTTPCommand-> httpGet-> END");
        return returnVal;
      }
      catch (IOException i) {
//        get.releaseConnection();
        Debug.getInstance().printUsingDebug(i);
 
        if (i instanceof SocketTimeoutException) {
 
          System.out.println("Timeout...Retrying " + retry);
 
          if (retry == retryCount) {
            Debug.getInstance().printUsingDebug(
                "AptiloHTTPCommand-> httpGet-> SOCKET_TIMEOUT_EXCEPTION");
            Debug.getInstance().printUsingDebug(i);
            logger.log(Level.SEVERE, "Timeout executing HTTP Get", i);
            get.releaseConnection();
            return new StringBuffer("" + ConnectorError.COM_TIME_OUT);
          }
          retry++;
          continue;
        }
 
        if (i instanceof SSLHandshakeException) {
 
          if (retry == retryCount) {
            get.releaseConnection();
            break;
          }
 
          System.out.println("Invalid Certificate Retrying " + retry);
 
          String tempresult = "";
          //Obtain the hostname in order to verify the certificate
          tempresult = obtainHost(cmdInstruction);
 
          if (tempresult.equals("998")) {
            Debug.getInstance().printUsingDebug(
                "AptiloHTTPCommand-> performTask-> END_ERROR_INVALID_HOST");
            get.releaseConnection();
            return new StringBuffer(tempresult);
          }
 
          //Verify the certificate
          validateCertificate cer = new validateCertificate();
          tempresult = cer.obtainCertificate(tempresult, keyStore,
password);
 
          if (tempresult.equals("998")) {
            Debug.getInstance().printUsingDebug(
                "AptiloHTTPCommand-> performTask->
END_ERROR_UNABLE_TO_OBTAIN_CERTIFICATE");
            get.releaseConnection();
            return new StringBuffer(tempresult);
          }
 
          retry++;
          continue;
        }
 
        Debug.getInstance().printUsingDebug(
            "AptiloHTTPCommand-> httpGet-> IO_EXCEPTION");
        Debug.getInstance().printUsingDebug(i);
        logger.log(Level.SEVERE, "Error executing HTTP Get", i);
        get.releaseConnection();
        return new StringBuffer("");
      }
    }
    Debug.getInstance().printUsingDebug(
        "AptiloHTTPCommand-> httpGet-> END_ERROR_RETRY_FAILED");
    return new StringBuffer("");
  }
 



Hi

i used the org.apache.commons.httpclient package to create this method. The
perpose of the method is to GET a given HTTPS url and obtain the result. If
the site requires a certificate then obtain it and store it in the specified
keystore and retry again.

The method works fine. eg:- If i try to GET to a url that requires a new
certificate then it obtains it and stores it in the keystore.

Heres where the problem is.

Say i want to send a GET command to a site named "ABC". eg:htps://ABC/......
Then my method will determine that i dont have the needed certificate,
obtain it from ABC and store it in the specified keystore. Then it should
retry to connect to ABC but even though it has saved the certificate the
program outputs a error no valid certificate found.

I know that the certificate is valid coz when i restart the program it
successfully connects to "ABC" and gets the output.

I think this has somthing to do with java's internal cache or HTTPS
sessions.

I noticed that it initialises the keystore only the first time it connects
to any site and until i restart my program it wont initialize the keystore
again. Meaning even if the method saves the new certificate in the keystore
the program seems to refer to the old keystore and not the updated one.

 

I tried using AuthSSLProtocolSocketFactory but it throws a error 

java.security.KeyStoreException: No private keys found in keystore!

And when I modify the keystore and add a new key I created via keytool I get
the message 

java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big. 



Please help

 

 

 

Reguards

 

Dhanushka Amrakoon

 


Re: HTTPS Certification problem

Posted by Roland Weber <os...@dubioso.net>.
Dhanushka Amarakoon wrote:

>     while (retry <= retryCount) {
>       System.setProperty("javax.net.ssl.trustStore", keyStore);
>  
>       HttpClient httpclient = new HttpClient();

That is bad. You should instantiate HttpClient only once
and re-use the instance. At the very least you should
shutdown the connection manager before forgetting about
an HttpClient instance. Used like this, your code is
leaking open socket connections, leaving them to mercy
of the garbage collector.

> I noticed that it initialises the keystore only the first time it connects
> to any site and until i restart my program it wont initialize the keystore
> again. Meaning even if the method saves the new certificate in the keystore
> the program seems to refer to the old keystore and not the updated one.

Exactly. The keystore is loaded once from the file to memory, then the
data in memory is used. I assume it is possible to update the keystore
explicitly at runtime, or to instantiate a new SSL context with the
modified keystore. Please refer to the SSL and JSSE documentation.

> I tried using AuthSSLProtocolSocketFactory but it throws a error 
> 
> java.security.KeyStoreException: No private keys found in keystore!
> 
> And when I modify the keystore and add a new key I created via keytool I get
> the message 
> 
> java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big. 

There are several different and incompatible formats for key stores.
You probably use the wrong one, or fail to tell the correct format
when loading the keystore. AuthSSLProtocolSocketFactory is meant to
be adapted to your specific needs, so you should dive into the code
and fix it until it works for you.
Have a look at not-yet-commons-ssl, it might help you with the
different keystore formats:
http://juliusdavies.ca/commons-ssl/

hope that helps,
  Roland





---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-user-help@jakarta.apache.org